在Java基础中,我们经常会碰到一个问题就是String的equal方法和==号的区别,对于有一定编程基础的小伙伴来说,中间的差别不言而喻,而对于初学者来说就有点模糊了,我们先应该有个大概的印象,对于String类来说,==是地址比较,equals是比较内容,本篇文章我们就从源码的角度去分析这个问题。
public static void main(String[] args) {
String word1 = "hello";
String word2 = "hello";
System.out.println(word1 == word2);
String a1 = new String("hello");
String b1 = new String("hello");
System.out.println(a1 == b1);
System.out.println(a1.equals(b1));
}
输出结果为true , false , true。
对于同一个==号,为什么上面的答案是true,下面的却是false呢?其实这就涉及到String在java的内存问题了。图中的word1和word2都为字符串常量,在编译期就放入到了常量池中,而new String实例化操作是在运行时才执行的,会在堆区中创建一个自己的地址空间,a1和b1分别new了一次,相当于在堆区开辟了两个地址空间。
我们再来看看String.equals()里面的源码,先是比较是不是同一个对象,也就是地址是否相同,再比较传入的对象是不是String类型,再比较传入的字符串长度,最后才比较每个字符串的值是否相等。
因为word1和word2是同一个字符常量,可以浅显的理解为两者在常量池中的地址是一样的,所以第一个结果为true,第二个结果a1和b1的地址不同,输出结果为false,第三个因为两者的字符内容一样,所以输出为true。特别要注意一点的是a1.equals(b1)中a1的值不能为null,否则系统会报空指针异常。