JDK源码学习--String篇(二) 关于String采用final修饰的思考
JDK源码学习String篇中,有一处错误,String类用final【不能被改变的】修饰,而我却写成静态的,感谢CTO-淼淼的指正。
风一样的码农提出的String为何采用final的设计,阅读JDK源码的时候,有粗略的思考过,今天下班后又把《Thinking in Java》中关于final的内容重新看了一遍,对此写下一些关于自己的理解和想法。
String类中final关键字的使用
final关键字,用来描述一块数据不能被改变,两种可能理由:设计、效率
final使用的三种情况:数据、方法、类,final修饰类,类不能被继承,final修饰方法,方法不能被重载
final对于基本类型的修饰,使得数值不能被改变,但是用于对象引用,虽然能保证初始化指定一个对象后,就无法指向其他对象,但是对象本身确实可以修改的。
, , }; a[] = ;
数组使用final修饰,引用地址不可改变,但是数组的数据却可以改变。
回过头来看String的源码设计中:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
}
String本质上就是一个char数组,使用final修饰,虽然引用不可变,但是内容可变。
所以 final char value[];无法保证String的不变性。
这时候将 class String 使用final修饰,value[] 使用private授予私有访问权限。禁止String类被继承,防止被子类改写,从而保证String的不可改变,这是出于安全性的考虑。
JAVA中参数传递的是传引用,所以多个变量可能指向的是同一个String,如果其中一个变量改变String的内容,另一个变量取到的是改变后的内容,不符合设计的初衷。
public static String testStr(String s, String b) {
s = b;
b += ";
return s;
}
public static void main(String[] args) {
String s = new String("aaa");
String b = new String("bbb");
String ns = Test.testStr(s, b);
System.out.println(s.toString());
}
关于效率的问题,涉及到JVM的处理机制,这一块不是很了解,以下内容节选自《Thinking in Java》
在Java的早期实现中,如果将一个方法声明为final,就是同意编译器将针对该方法的所有调用都转为内嵌调用。当编译器发现一个final方法调用命令时,它会根据自己的谨慎判断,跳过插入程序代码的这种正常方式而执行方法调用机制(将参数压入栈,跳至方法代码处并执行,然后跳回并清理栈中的参数,处理返回值),并且以方法体中的实际代码的副本来代替方法调用。这将消除方法调用的开销。
JDK源码学习--String篇(二) 关于String采用final修饰的思考的更多相关文章
- JDK源码学习系列03----StringBuffer+StringBuilder
JDK源码学习系列03----StringBuffer+StringBuilder 由于前面学习了StringBuffer和StringBuilder的父类A ...
- JDK源码学习系列01----String
JDK源码学习系列01----String 写在最前面: 这是我JDK源码学习系列的第一篇博文,我知道 ...
- JDK源码学习系列02----AbstractStringBuilder
JDK源码学习系列02----AbstractStringBuilder 因为看StringBuffer 和 StringBuilder 的源码时发现两者都继承了AbstractStringBuil ...
- JDK源码学习笔记——Enum枚举使用及原理
一.为什么使用枚举 什么时候应该使用枚举呢?每当需要一组固定的常量的时候,如一周的天数.一年四季等.或者是在我们编译前就知道其包含的所有值的集合. 利用 public final static 完全可 ...
- JDK源码学习笔记——LinkedHashMap
HashMap有一个问题,就是迭代HashMap的顺序并不是HashMap放置的顺序,也就是无序. LinkedHashMap保证了元素迭代的顺序.该迭代顺序可以是插入顺序或者是访问顺序.通过维护一个 ...
- JDK源码学习系列05----LinkedList
JDK源码学习系列05----LinkedList 1.LinkedList简介 LinkedList是基于双向链表实 ...
- JDK源码学习系列04----ArrayList
JDK源码学习系列04----ArrayList 1. ...
- JDK源码学习--String篇(-)
工作三年了,用了三年的JAVA,突然发现竟然没有好好的看下JDK的源码,整天用着的String,只是大概知道怎么回事,其中的实现逻辑却是一头雾水. 知耻而后勇,加油!!! java.lang.Stri ...
- JDK源码学习--String篇(四) 终结篇
StringBuilder和StringBuffer 前面讲到String是不可变的,如果需要可变的字符串将如何使用和操作呢?JAVA提供了连个操作可变字符串的类,StringBuilder和Stri ...
随机推荐
- hdu 5584 LCM Walk(数学推导公式,规律)
Problem Description A frog has just learned some number theory, and can't wait to show his ability t ...
- python写xml文件
为了便于后续的读取处理,这里就将信息保存在xml文件中,想到得到的文件如下: 1 <?xml version="1.0" encoding="utf-8" ...
- Tkinter类之窗口部件类
Tkinter类之窗口部件类 Tkinter支持15个核心的窗口部件,这个15个核心窗口部件类列表如下:窗口部件及说明:Button:一个简单的按钮,用来执行一个命令或别的操作.Canvas:组织图形 ...
- wdos相关问题解答
wdos系统自动分区的大小说明 wdOS系统提供了可自动分区和手工分区 自动分区适用大部分新手或对分区没有特的要求的人 手工分区适用老手或熟悉分区或有特别需求的人 具体用哪个,没多大区别,关键是看应用 ...
- 最简单的视音频播放演示样例4:Direct3D播放RGB(通过Texture)
===================================================== 最简单的视音频播放演示样例系列文章列表: 最简单的视音频播放演示样例1:总述 最简单的视音频 ...
- LCD与ARM,具体
一 实验内容简要描写叙述 1.实验目的 学会驱动程序的编写方法,配置S3C2410的LCD驱动,以及在LCD屏上显示包含bmp和jpeg两种格式的图片 2.实验内容 (1)分析S3c2410实验箱 ...
- 图片延迟加载技术-Lazyload的应用
我们在浏览图片量非常大的页面时,像淘宝商城商品展示.必应图片搜索这类网站,图片的加载非常流畅,其中就应用了图片延迟加载技术.本文讲解Lazyload图片加载插件,当我们打开页面时,首先在屏幕可视区域加 ...
- `npm install --save --save-exact react-native` failed
当你使用命令行创建一个项目 react-native init 项目名称 后出现以下错误 Installing react-native package from npm... /bin/sh: ...
- 解析word中的表格
由于word表格的特殊性,其本身中的数据本来就不够完善,不能够很好的知道其具体的合并.跨行的相关属性,表格的单位可能是PT或者是百分比,并且是共存的,为处理带来了一定的负担,本代码实现了一个将Word ...
- NotificationManager 发送通知
该应用的界面如下,界面代码在此不再给出,源码github账户下载 MainActivity.java public class MainActivity extends Activity { priv ...