java 中的==和equals的深度解析

1、问题产生

先看下面的代码

public class StringDemo {  
  public static void main(String[] args) {  
            String str1 = "hello";  
            String str2 = new String("hello");  
            String str3 = str2;  
            System.out.println("str1==str2:"+(str1==str2));   false
            System.out.println("str1==str3:"+(str1==str3));  false
            System.out.println("str2==str3:"+(str2==str3));  true
        }  
}  

why?为什么会这样打印呢?上面的例子str1、str2、str3的内容都是一样的但比较的结果却是有的相等,有的不相等,这是为啥?
首先看一张内存上述的内存分配图

从图中可以清楚的发现每个String对象的内容实际是保存到堆内存中的,而且堆中的内容是相等的。但是对于str1和str2来说所指向的地址堆内存地址是不等的,所以尽管内容是相等的,但是地址值是不相等的,“==”是用来进行数值比较的,所以str1和str2比较不相等,因为str2和str3指向同一个内存地址,所以str2和str3是相等的。所以“==”是用来进行地址值比较的。str1、str2、str3中都是存放的地址。字符串常量都是存放的地址,==比较地址,equals比较内容
那么怎么判断两个字符串的内容是否相等呢?我们先看个例子

public class StringDemo {  
    public static void main(String[] args) {  
        String str1 = "hello";  
        String str2 = new String("hello");  
        String str3 = str2;  
        System.out.println("str1 equals str2:"+(str1.equals(str2)));  true
        System.out.println("str1 equals str2:"+(str1.equals(str3)));  true
        System.out.println("str1 equals str2:"+(str2.equals(str3)));  true
    }  
}  

因为equals方法的作用是将内容进行比较,所以此处的返回结果都为true。
总结以上两个例子我们可以总结出"=="和equals的区别是:“==”是用来进行数值比较的,在String中用“==”进行地址值的比较,而equals比较的是String的内容。

2、深度解析

String创建对象时系统会自动创建一个字符串缓冲池,在你进行如String str = "a";之类的操作时,系统会先在缓冲池中寻找有没有,如果没有就会创建一个。
String s1 = "abc";
String s2 = "abc";
创建了一个对象,s1和s2指向同一个对象,
String s1 = "abc";
String s2 = new String( "abc" );
创建了两个对象
这里由于s2用的是new,所以系统会分配一个新的引用地址给s2不会使用s1的引用地址
详细分析请参考博主的已另一篇博客jvm内存模型概述

猜你喜欢

转载自www.cnblogs.com/zhangke306shdx/p/11014554.html