Java开发之道
上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 类来执行。