运算符==
利用“==”判断两个变量是否相等时
1、如果两个变量是基本类型变量,且都是数值类型(不一定要求数据类型严格相同),则只要两个变量的值相等,就将返回true。
public static void judge(){
int num1 = 65;
float num2 = 65.0F;
char num3 = 'A';
System.out.println(num1==num2); // true
System.out.println(num1==num3); // true
System.out.println(num2==num3); // true
}
2、如果比较两个引用类型变量,只有它们指向同一个对象时,“==”判断才会返回true。
原理如下图:
对比如下两段代码的结果:
代码一:引用类型!!!
public static void judge(){
String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1==str2); // false
}
代码二:字符串哦!!!
String引用类重写了equals()方法
public static void judge(){
String str3 = "Hello";
String str4 = "Hello";
System.out.println(str3==str4); // true
}
注意:==不可以比较类型上没有父子关系的两个对象。
常量池(constant pool)
1、专门用于管理在编译时被确定并被保存在已编译的class文件中的一些数据。
2、包括了关于类、方法、接口中的常量,还包括字符串中的常量。
根据如下代码的输出体会差别:
public static void judge1(){
// s1直接引用常量池中的“985高校”
String s1 = "985高校";
String s2 = "985";
String s3 = "高校";
// s4后面的字符串值可以在编译时就确定下来
// s4直接引用常量池中的“985高校”
String s4 = "985" + "高校";
// s5后面的字符串值可以在编译时就确定下来
// s5直接引用常量池中的“985高校”
String s5 = "9" + "8" + "5" + "高" + "校";
// s6后面的字符串值不可以在编译时就确定下来
// 不能引用常量池中的字符串
String s6 = s2+s3;
// 使用new调用构造器将会创建一个新的String对象
// s7引用堆内存中新创建的String对象
String s7 = new String("985高校");
System.out.println(s1==s4); // true
System.out.println(s1==s5); // true
System.out.println(s1==s6); // false
System.out.println(s1==s7); // false
}
1、JVM常量池保证相同的字符串直接常量只有一个,不会产生多个副本。
2、上述代码中的s1、s4、s5所引用的字符串可以在编译器就确定下来,因此它们将引用常量池中的同一个字符串对象。
3、使用new String()创建的字符串对象是运行时创建出来的,它被保存在运行时内存区(堆内存)内,不会放入常量池。
equals()
大多时候,程序判断两个引用变量是否相等时,也希望有一种类似于“值相等”的判断规则,并不严格要求两个引用变量指向同一对象。此时 就可以利用String对象的equals()方法来进行判断。
equals()方法来源
equals()方法是Object类提供的一个实例方法,因此所有引用变量都可以调用该方法来判断是否与其它引用变量相等。但是使用这个方法判断两个对象相等的标准与使用恒等运算符没有区别,同样要求两个引用变量指向同一个对象才会返回true。
因此,Object类提供的equals()方法没有太大的实际意义,如果希望采用自定义的相等标准,则可以采用重写equals方法来实现。例如String类中就重写了equals方法。
常用的类中没有重写equals()方法如下:
public class EqualsNotice {
public static void main(String[] args) {
// StringBufer类中没有重写equals方法,
// 因此直接使用的该方法属于Object类
StringBuffer sb1 = new StringBuffer("字符串");
StringBuffer sb2 = new StringBuffer("字符串");
System.out.println(sb1.equals(sb2)); // false
}
}
实际开发中
1、在实际应用中,重写equals()方法就是提供自定义的相等标准,我们自己认为怎么是相等,那就怎样了是相等,一切都由需求来定义。
2、
在极端情况下可以让Person对象和Dog对象相等。
下面两段代码都重写了equals方法
代码一:
代码二:
重写equals()要满足如下规则:
1、自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
2、对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
3、传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
4、一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
5、对于任何非空引用值 x,x.equals(null) 都应返回 false。
Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。
注意:
1、当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
2、重写equals()时,相等条件是由业务决定的,因此equals()方法的实现也是由业务要求决定的。
3、实际开发中,字符串的比较几乎都是用equals().