==和equals()

常量池(constant pool)专门用于管理在编译时被确定并保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口中的常量,还包括字符串常量。

首先需要了解一下“hello”直接量和new String(“hello”)有什么区别:当Java程序直接使用如“hello”的字符串直接量(包括可以在编译时就计算出来的字符串值)时,JVM将会使用常量池来管理这些字符串;当使用new String(“hello”)时,JVM会先使用常量池来管理“hello”直接量,再调用String类的构造器来创建一个新的String对象,新创建的String对象被保存在堆内存中。也就是说,new String(“hello”)一共产生了两个字符串对象。

public class StringCompareTest {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //s1直接引用常量池中的"hello world"
        String s1 = "hello world";   
        String s2 = "hello";
        String s3 = "world";
        //s4后面的字符串值可以在编译时就确定下来,直接引用常量池中的"hello world"
        String s4 = "hello" + " " + "world";
        //s5后面的字符串值不能在编译时确定下来,不能直接引用常量池中的字符串
        String s5 = s2 + " " + s3;
        //使用new调用构造器将会创建一个新的String对象,s6引用堆内存中新创建的String对象
        String s6 = new String("hello world");
        System.out.println(s1 == s4);
        System.out.println(s1 == s5);
        System.out.println(s1 == s6);   
        System.out.println(s1.equals(s4));  
        System.out.println(s1.equals(s5));  
        System.out.println(s1.equals(s6));  
    }
}

运行结果如下:
这里写图片描述
JVM常量池保证相同的字符串直接量只有一个,不会产生多个副本。上述代码中的s1和s4所引用的字符串在编译初期就可以确定下来,因此它们都将引用常量池中的同一个字符串对象。
使用new String()创建的字符串对象是运行时创建出来的,它被保存在运行时内存区(即堆内存)内,不会放入常量池。因此在以上代码中s1==s4结果为true,s1==s4和s1==s5结果为false。
针对以上情况若是只需要比较值是否相等则可以使用String的equals()方法,返回结果如图都为true。


Object类提供了equals()方法,因此所有引用常量都可以调用该方法来判断是否与其他引用变量是否相等,但这个方法也只有在两个引用常量指向同一个对象时才会返回true。因此常会将其重写实现所需功能。
String已经重写了Object类的equals()方法,String类的equals()方法认为只要两个字符串所包含的字符序列相同,就返回true,否则返回false。如上代码所示。

猜你喜欢

转载自blog.csdn.net/qq_37111953/article/details/79499031