首先
String有两种创建方法。
String str=“aa ";
stringstr1=新字符串(“BBB”);
还要知道字符串是不变的,创建后不能修改。 文章稍后再用。
这两种创建方法的区别是什么?
让我们先来看一个最简单的例子:
答案很明显。 false true。
首先,要知道Java有字符串常量池。 使用str1=“AADD”创建字符串时,首先查找字符串常量池中是否存在此字符串,如果没有,则直接引用此现有字符串,如果没有,则在池中创建,然后引用刚刚创建的字符串。 这也是我们看到的(str1==str3)为什么会为真的原因。 str1已经创建了“添加”,但此时str3在创建时直接引用了相同的字符串。 他们保管的是同样的引用。 值也相同。
使用new关键字创建字符串时,实际上会在堆中创建字符串对象" AADD ' "。 请注意,此对象与str1创建的对象不同。 另一方面,str3存储堆中“添加”的引用。 当然,它与str1存储的池中的引用完全不同。 不相等。
接下来,请看这个代码:
结果为false true
我相信我能做到这个,在你面前已经明白了。 str1的操作实际上相当于我们的第一个创建方法,如果不在常量池中,则直接在池中创建“justso so”。
代码在str2中执行的行与第一个图相同,一个存储在池中,因此当然不同。
接下来是名为str3的行。 此时,str3在常量池中找到“justso so”后,不在池中新建,而是直接引用在str1中创建的对象。 两个引用相同,自然结果为true。
也可以通过查看地址的值来显示地址。 (System.identityHashCode )是一种可以显示混列地址的方法。)
这是取消注释的结果,表明str1和str2的地址完全不同,str3与str1相同。
str1hashcode:366712642
str2hashcode:1829164700
假的
str1hashcode:366712642
str3hashcode:366712642
真的
*重点就在这里。 **上图:
结果: false。
输出地址:
str3 hashcode:366712642
str4 hashcode:1829164700
最后明白是因为字符串不是可变的。
可以看到,String类采用添加了final的数组作为保存字符串的方法。 * *对于**final变量,对于基本数据类型,值在重新初始化后无法更改。 对于引用数据类型,初始化后不能指向其他对象。 *因此,实际上,只需创建新字符串,并为原始字符串变量提供新字符串的引用。 String str='abcde '; str=str 'gf '; system.out.println(str; 结果: abcdegf虽然看起来像是str在进行连接操作,但实际上前后的地址不同:
String str='abcde ';
system.out.println (str hashcode : ) system.identity hashcode (str );
str=str 'gf ';
system.out.println (str hashcode : ) system.identity hashcode (str );
system.out.println(str;
结果:
strhashcode:366712642
strhashcode:1829164700
abcdegf
这是因为,在进行字符串常量的操作时,实际上new调用StringBuilder对象(可变字符串,调用append ) )方法,完成操作的缝合后,调用toString ) )方法由于这一系列操作在堆中进行,因此上图中的str3在执行str1 str2操作后返回堆中的引用。 因此,它与在池中创建的名为str4的对象不同。