在正式开始之前,先来看一个有趣的程序吧:
int a = 100, b = 100;
System.out.println(a == b);//(1) true
int c = 1000, d = 1000;
System.out.println(c == d);//(2) true
Integer e = 100, f = 100;
System.out.println(e == f); //(3) true
Integer g = 1000, h = 1000;
System.out.println(g == h); //(4) false
上面的程序大家都知道(1)(2)输出的是true,这是肯定没错的!
But(3)(4)输出的也是true吗?答案是否定的,运行一下程序得到的结果是(3)为true,(4)为false!!
先来解释一下上面的原因:如果你看去看 Integer.java 类,你会发现有一个内部私有类,IntegerCache.java,它缓存了从-128到127之间的所有的整数对象。所以如果值范围在-128-127之间,它就从高速缓存中返回实例,所以e、f就指向了同一个对象,结果返回true。这里使用缓存的理由是在此范围内的“小”整数使用率比大整数要高,因此,使用相同的底层对象是有价值的,可以减少潜在的内存占用。
上面讲述了“==”,进一步联想思考和判等相似的还有一个“equals”,举例程序如下:
String str1 = new String("test");
String str2 = new String("test");
System.out.println(str1 == str2); //(5) false
System.out.println(str1.equals(str2));//(6) true
结果(5)输出false,(6)输出true!
我们知道,Java中两个比较方式,“==”与“equals”:
“==”可以用来比较两个基本类型的数值是否相等,同时如果两个引用指向同一个对象则它们也是相等的;如果两个引用指向不同的对象,即使它们的内容相同用“==”表示它们是不相等的。此时需要用equals来比较,equals方法比较两个独立对象的内容是否相同(equal比较字符串时比较的是字符序列是否相等),并且equal方法是java.lang.Object的方法,也就是所有Java类都会有的方法,它可以被程序员覆盖重写,通过自定义的方式来判断两个对象是否相等。所以(5)的结果为false,而(6)的结果为true。
(这里说明一下,Java中的基本类型有boolean,byte,short,char,int,float,double,long,Java.lang.String是final类型)
知道了“==”和“equals”的用法,我们来自己写一类测试一下刚才的说法:
class Stu{
String name;
Stu(){
name = "";
}
Stu(String name, int age, int score){
this.name = name;
}
}
Stu stu1 = new Stu("Jack", 24, 100);
Stu stu2 = new Stu("Jack", 24, 100);
System.out.println(stu1 == stu2); // false
System.out.println(stu1.equals(stu2));// false
自定义一个类,然后再用“==”和“equals”比较,又发生变化了,“equals”又不起作用了啊???
查一查原因是如果一个类没有自己定义 equals 方法,那么它将继承 Object 类的 equals 方法,而Object 类的 equals 方法的实现代码如下:
boolean equals(Object o){
return this==o;
}
class Stu{
String name;
Stu(){
name = "";
}
Stu(String name, int age, int score){
this.name = name;
}
boolean equals(Stu stu){
return this.name == stu.name;
}
}
Stu stu1 = new Stu("Jack", 24, 100);
Stu stu2 = new Stu("Jack", 24, 100);
System.out.println(stu1 == stu2); // false
System.out.println(stu1.equals(stu2));// true
结果就自然而然出来了!!!