上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人
谬误14 不知其二——字符串是值类型
Java 字符串是使用String 关键字声明的、由一个或多个字符构成的一组字符,由于它可以方便地携带各种信息,因此字符串在程序代码中被广泛应用。
Java中的字符串是String类型,通过查看String类型的元数据可以看到,该类型直接继承自Object对象。但String类型的某些特性会让人产生它属于值类型的错觉,如下面的代码:
public class Test { //main方法 public static void main (String[] args) { String str1 = "这是第一个字符串"; String str2 = str1; // 把str1的引用传递给str2 System.out. println (str1. equals (str2)); // 两个字符串的引用指向同一个内存地址 str2 = "这是第二个字符串"; // 试图使用引用str2修改str1指向的对象 System.out. println (str1. equals (str2)); // 两个字符串的引用不指向同一个内存地址 } }
注意
由于字符串是引用类型,将str1的引用传递给str2之后,两个字符串变量指向同一内存地址,修改str2的内容之后,str1和str2也应该指向同一内存地址。但实际的运行结果是修改str2内容之后,两个字符串变量指向了不同的内存地址。
运行上述代码后,在控制台输出的效果如图4.10所示。
图4.10 字符串判断是否相等输出的信息
这样的执行结果很容易让人产生错觉,误以为String 属于值类型。分析其原因,是由于String类创建的字符串对象的不可修改的特性所致。使用String对类创建字符串对象后,就不能再做修改(如插入、删除等),若修改,则会马上生成新的字符串对象,也就是说,String类创建的字符串对象是一个只读的对象。在上面代码中,将“这是第二个字符串”赋给str2时,实际上是初始化一个新的字符串对象并且赋给了引用str2,这就是出现上面的运行结果的原因。
技巧
String类创建的字符串对象不可变,因此一旦创建就不能更改。对字符串进行操作的方法实际会返回新的字符串对象。因此,出于性能方面的考虑,大量连接或其他涉及的字符串操作应通过StringBuffer 类来执行。