Java中==和equals方法
Java程序中测试两个变量是否相等有两种方式:1、== ;2、equals()方法
当使用==来判断两个变量是否相等时,如果两个变量是基本类型变量,且都是基本数值类型(不一定要求数据类型严格相同),则只要两个变量的值相等,就返回true。
但对于两个引用类型的变量,只有他们指向同一个对象时,==判断才会返回true。==不可用于比较类型上没有父子关系的两个对象。
public class EqualTest { public static void main(String[] args) { // TODO Auto-generated method stub int it = 65; float fl = 65.0f; System.out.println("65和65.0f是否相等?" + (it == fl)); String str1 = new String("hello"); String str2 = new String("hello"); System.out.println("str1是否与str2相等?" + (str1==str2)); System.out.println("str1是否与str2相等?" + (str1.equals(str2))); } }
结果如下:
65和65.0f是否相等?true str1是否与str2相等?false str1是否与str2相等?true
解析:对于str1和str2,因为它们都是引用类型变量,它们分别指向两个通过new关键字创建的String对象,因此str1和str2两个变量不相等。
对初学者而言,String还有一个非常容易迷惑的地方,“hello”直接量和new String("hello")有什么区别?JVM将会使用常量池来管理这些字符串;当使用new String("hello")时,JVM会先使用常量池来管理“hello”直接量,再调用String类的构造函数来创建一个新的String对象,新创建的String对象被保存在堆内存中,换句话说,new String("hello")一共产生两个字符串变量。
常量池
常量池专门用于管理在编译时被确定并被保存在已编译的.class文件中的一些数据。包括关于类、方法、接口中的常量,还包括字符串常量。
public class EqualTest { public static void main(String[] args) { // TODO Auto-generated method stub String s1 = "helloworld"; String s2 = "hello"; String s3 = "world"; String s4 = "hello"+"world"; String s5 = s2+s3; String s6 = new String("helloworld"); System.out.println("s1是否与s4相等?" + (s1==s4));//true System.out.println("s1是否与s5相等?" + (s1==s5));//false System.out.println("s1是否与s6相等?" + (s1==s6));//false } }
JVM常量池保证相同的字符串直接量只有一个,不会产生多个副本。故例子中s1和s4所引用的字符串可以在编译期就确定下来。它们引用常量池中同一个字符串对象。
使用new String()创建出来的字符串对象时运行时创建出来的,它被保存在运行时内存区(堆内存),不会放到常量池中。
但很多时候希望,程序判断两个引用变量是否相等时,也希望有一种类似“值相等”的判断规则,并不严格要求两个引用变量指向同一对象,可以利用equal()方法。
equal()方法是Object类提供的一个实例方法,因此所有引用变量都可以调用该方法来判断是否与其他引用变量相等。但使用该方法判断两个对象相等的标准与使用==运算符没有区别,同样要求两个引用变量指向同一个对象才会返回true。如果采用自定义的相等标准,则可采用重写equals方法实现。
String已经重写了equals()方法,判断两个字符串相等的标准:只要两个字符串所包含的字符序列相同。
class Person { public String getName() { return name; } public void setName(String name) { this.name = name; } public String getIdStr() { return idStr; } public void setIdStr(String idStr) { this.idStr = idStr; } private String name; private String idStr; public Person(){} public Person(String name , String idStr) { this.name = name; this.idStr = idStr; } public boolean equals(Object obj) { if(this == obj) return true; if(obj != null && obj.getClass() == Person.class) { Person personobj = (Person)obj; if(this.getIdStr().equals(personobj.getIdStr())){ return true; } } return false; } } public class OverrideEqualsRight { public static void main(String[] args) { // TODO Auto-generated method stub Person p1 = new Person("xiaoming","123"); Person p2 = new Person("xiao","123"); Person p3 = new Person("da","12345"); System.out.println("p1和p2是否相等?"+p1.equals(p2)); System.out.println("p2和p3是否相等?"+p2.equals(p3)); } }
p1和p2是否相等?true p2和p3是否相等?false