(3 )将str指向对象o的地址。
值得留心 的是,一般String类中字符串值都是直接存值的。但像String str = "abc" ;这种场合下,其字符串值却是保存了一个指向存在栈中数据的引用!
为了更好地说明这个疑问 ,我们可以通过以下的多个 代码执行 验证。
String str1 = "abc" ;
String str2 = "abc" ;
System.out.println(str1==str2); //true
留心 ,我们这里并不用str1.equals(str2);的方式,因为这将比较两个字符串的值能不能 相等。==号,根据JDK的说明,只有在两个引用都指向了同一个对象时才返回真值。而我们在这里要看的是,str1与str2能不能 都指向了同一个对象。
结果说明,JVM建立 了两个引用str1和str2,但只建立 了一个对象,而且两个引用都指向了这个对象。
我们再来更进一步,将以上代码改成:
String str1 = "abc" ;
String str2 = "abc" ;
str1 = "bcd" ;
System.out.println(str1 + "," + str2); //bcd, abc
System.out.println(str1==str2); //false
这就是说,赋值的变化导致了类对象引用的变化,str1指向了另外一个新对象!而str2仍旧指向原来的对象。上例中,当我们将str1的值改为"bcd" 时,JVM发觉 在栈中没有存放该值的地址,便开辟了这个地址,并建立 了一个新的对象,其字符串的值指向这个地址。
事实上,String类被设计成为不可改动 (immutable)的类。如果你要改动 其值,可以,但JVM在运行时根据新值悄悄建立了一个新对象,然后将这个对象的地址返回给原来类的引用。这个建立 流程 虽说是完全自动执行的,但它毕竟占用了更多的时间。在对时间要求比较敏感的环境中,会带有一定的不良影响。
再修改原来代码:
String str1 = "abc" ;
String str2 = "abc" ;
str1 = "bcd" ;
String str3 = str1;
System.out.println(str3); //bcd
String str4 = "bcd" ;