1.基本类型
因为java中的8中基本类型都不是对象,不存在equals方法,只能用“==”比较内容。
2.对象
在Object中,equals方法和“==”都是比较对象在堆内的首地址,即判断两个引用变量是否指向同一个对象。
除非重写了equals方法。
3.包装类型
在包装类型中,都重写了equals方法,所以比较的是对象的内容是否相等。而“==”比较的是地址。
另外除了8种包装类型,String,Date也重写了equals方法
4.example
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
Long h = 2L;
String str1="hello";
String str2="hello";
String str3=new String("hello");
String str4=new String("hello");
String str5="he"+new String("llo");
StringBuffer str6=new StringBuffer("hello");
StringBuffer str7=new StringBuffer("hello");
Object o1=new Object();
Object o2=new Object();
System.out.println(c==d); //1 true
System.out.println(e==f); //2 false
System.out.println(c==(a+b)); //3 true
System.out.println(c.equals(a+b)); //4 true
System.out.println(g==(a+b)); //5 true
System.out.println(g.equals(a+b)); //6 false
System.out.println(g.equals(a+h)); //7 true 以上包装类型
System.out.println(str1==str2); //8 true
System.out.println(str1.equals(str2));//9 true
System.out.println(str1==str3); //10 false
System.out.println(str1.equals(str3));//11 true
System.out.println(str3==str4); //12 false
System.out.println(str4==str5); //13 false
System.out.println(str1==str5); //14 false
System.out.println(str1.equals(str5));//15 true
System.out.println(str6==str7); //16 false
System.out.println(str6.equals(str7));//17 false
System.out.println(o1==o2); //18 false
System.out.println(o1.equals(o2)); //18 false
}
结果解析:
1-7 考虑是数据的包装类型,值得注意的是==原本比较的是引用变量是否指向同一个对象,但是进行运算时a+b,会自动拆箱,因此==比较的是内容。而如果时equals(a+b),则会先进行拆箱,运算后再装箱。Integer的缓冲池是[-128,127],如果在此范围之内,返回同一引用,否则,要重新new对象。所以1true,2false ,3数值内容相同true,4触发自动拆箱运算再装箱,比较的值true ,5 值同true
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
以上为Long重写的equals方法。6 a+b装箱为Integer 非Long,false , 7 a+h 精度升级,所以封装为Long。
8.常量赋值字符串时,会创建一个字符串缓冲池。所以赋值str2时,会先去字符串缓冲池中查找相同的对象,如果有直接返回引用,没有再创建。true, 9 true 10 str3用的new,重新申请的空间,false 12重新new,申请了两个不同的空间 false 17 StringBuffer 没有重写equals方法,继承了Object中的equals,比较的是堆内的首地址false
5.补充
1.System.out.println(str1==str3.intern()); --->true 原因:intern方法返回“hello”,但是进行了处理,去字符串缓冲池中查找“hello”,如果存在直接返回,不存在则在缓冲池中创建,然后再返回引用。
2. Float f1=1f;Float f2=2f; System.out.println(f1==f2); --->false 原因8种包装类型中long和float都是没有缓存池的。因为比起Integer来说在一定的范围内,该类型所持有的数量是不一定的。