String a = "ab"; String b = "a" + "b"; a == b 吗?

在Java中,String对象是不可变的,即一旦创建后,其内容不能被修改。对于字符串对象的比较,使用==比较的是引用地址,而使用.equals()方法比较的是字符串的内容。现在让我们来详细解释下这个问题,并结合代码进行演示。

public class StringComparisonDemo {
    public static void main(String[] args) {
        String a = "ab"; // 在编译时常量池中创建 "ab" 字符串对象
        String b = "a" + "b"; // 在编译时常量池中创建 "ab" 字符串对象

        // 判断是否为同一个引用
        System.out.println("a == b: " + (a == b)); // 输出 true,因为 a 和 b 都指向编译时常量池中的同一个对象

        // 判断内容是否相同
        System.out.println("a.equals(b): " + a.equals(b)); // 输出 true,因为 a 和 b 的内容都是 "ab"
    }
}

输出结果为:

a == b: true
a.equals(b): true

从输出结果可以看出,ab的引用地址是相同的,因此a == b返回true。同时,它们的内容也相同,因此a.equals(b)返回true

原因解析:
在Java中,字符串连接表达式"a" + "b"会在编译时被优化,将其直接转换为一个字符串常量"ab"。因此,b实际上指向编译时常量池中的"ab"字符串对象,与a指向的对象是同一个。

值得注意的是,如果字符串连接表达式中存在变量,那么在运行时就无法在编译时进行优化了,例如:

public class StringComparisonDemo {
    public static void main(String[] args) {
        String a = "ab"; // 在编译时常量池中创建 "ab" 字符串对象
        String x = "a";
        String y = "b";
        String b = x + y; // 运行时连接 x 和 y,创建新的字符串对象

        // 判断是否为同一个引用
        System.out.println("a == b: " + (a == b)); // 输出 false,a 和 b 的引用地址不同

        // 判断内容是否相同
        System.out.println("a.equals(b): " + a.equals(b)); // 输出 true,a 和 b 的内容都是 "ab"
    }
}

输出结果为:

a == b: false
a.equals(b): true

在这个例子中,由于xy是变量,因此字符串连接表达式x + y在运行时才能确定结果。所以,b是在堆中新创建的一个字符串对象,其引用地址与a不同。但是由于内容相同,a.equals(b)仍然返回true

赞赏