"==" 与 equals 比较字符串对象

"==" 与 equals 在字符串比较中的不同

"==" 比较的是字符串的地址值,是不是同一份内存空间的地址(相同引用)
equals 比较的是字符串的内容,同一个内存空间地址里值(相同内容)

例如:

public static void main(String[] args) {
    String str1 = new String("abc");
    String str2 = new String("abc");
    String str3;
    str3 = str1;

    System.out.println(str1 == str2);//false
    System.out.println(str1.equals(str2));//true
    System.out.println(str1 == str3);//true
    System.out.println(str1.equals(str3));//true
    System.out.println(str1.equals(null));//false
}  

str1 与 str2 会在堆内存中创建字符串对象,两者有不同的内存地址(0x0001与0x0002),但是用equals比较两者存储的内容时一致的,新定义的变量str3指向了str 相同的内存地址(0x0001),所以无论是比较内存地址和字符串内容都相等,注意任何字符串与null常量比较都是false.

我们再看以下代码:

    String str4 = "abc";
    String str5 = "abc";
    System.out.println(str4==str5);//true
    System.out.println(str4.equals(str5));//true
    String str6 = new String("abc");
    System.out.println(str6==str4);//false  

那么这里为什么输出true呢,因为字符串"abc"是字符串常量池中取出来的.

什么是String Pool(String池):

专门用来存储字符串常量,可以提高内存的使用率,避免开辟多块空间存储相同的字符串,在创建字符串时JVM会首先检查字符串常量池,如果该字符已经存在池中,则返回它的引用,如果不存在,则实例化一个字符串放到池中,并返回其引用。

所以采用直接创建String类型对象的方法创建对象时,JVM首先会去字符串常量池中查找是否存在"abc" 这个对象,如果不存在,则在字符串常量池中创建”abc“这个对象,然后将池中”abc“对象的引用地址返回给对象str4,这样str4的地址就在常量池中;
如果存在,则不创建任何对象,直接将存在的“abc”的地址返回给对象str5。这就是为什么str4等于str5的原因。

而通过new方法创建的str6对象,创建的字符串是放在堆当中的,将堆当中的字符串地址返回赋值给str6,str4和str6的存放地址不相同,一个在字符串常量池中,一个在堆当中,因此返回的值是false。

posted @ 2022-12-24 19:06  OKGOsky  阅读(40)  评论(0)    收藏  举报