首先Java中的数据类型分为
对于这八种基本数据类型的变量,变量直接存储的是“值”。
所以,在八种基本类型中使用关系操作符 == 来进行比较时,比较的就是“值”本身。
在Java中,引用类型的变量存储的并不是“值”本身,而是与其关联的对象在内存中的地址。
比如下面这行代码
String str1;
这句话声明了一个引用类型的变量,此时它并没有和任何对象关联。
而通过 new 来产生一个对象,并将这个对象和str1进行绑定:
str1= new String("hello");
那么 str1 就指向了这个对象,此时引用变量str1中存储的是它指向的对象在内存中的存储地址,并不是“值”本身,也就是说并不是直接存储的字符串”hello”。这里面的引用和 C/C++ 中的指针很类似。
因此,对于关系操作符 ==:
为了更直观地理解equals方法的作用,我们先看Object类中equals方法的实现。
public boolean equals(Object obj) { return (this == obj); }通过代码可以看到,Object类里的equals方法也就是直接使用==。
但我们都知道,下面代码输出为 true:
public class Main {
public static void main(String[] args) {
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1.equals(str2));
}
}
再看一下String类的equals方法
public boolean equals(Object anObject) { // 先比较两个对象对否指向同一个内存地址 // 如果相等直接返回true if (this == anObject) { return true; } // 判断类型是否相等 if (anObject instanceof String) { String anotherString = (String)anObject; // 取当前字符串的长度 int n = value.length; // 判断字符串的长度是否相等 if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; // 逐字符判断是否相等,如果有一个字符不相等,则返回false while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } // 如果所有字符都相等,则返回true return true; } } // 如果类型不相等,直接返回false return false; }
可以看到String重写了equals()方法
------------------------------------------------------------------------------------------
对象不同,内容相同
"=="返回false,equals返回true
String s1 = new String("java");
String s2 = new String("java");
System.out.println(s1==s2); //false
System.out.println(s1.equals(s2)); //true
同一对象
"=="和equals结果相同
String s1 = new String("java");
String s2 = s1;
System.out.println(s1==s2); //true
System.out.println(s1.equals(s2)); //true
如果值不相同,则肯定不是相同的对象
所以在这种情况下"==" 和equals结果一样
String s1 = "java";
String s2 = "java";
System.out.println(s1==s2); //true
System.out.println(s1.equals(s2)); //true
使用方法二创建String时,首先冲缓冲池中找有没有相同的值,如果有则直接指向它。所以这里s1==s2为true
两个语句都是返回一个String对象的引用, 但JVM处理的方式不一样.