6.2.2 ==和equals方法

6.2.2 ==和equals方法

Java程序中测试两个变量是否相等有两种方式:

  • 一种是利用==运算符,
  • 另一种是利用equals()方法。

当使用==来判断两个变量是否相等时,
如果两个变量是基本类型变量,且都是数值类型(不一定要求数据类型严格相同),则只要两个变量的值相等,就将返回true
如果两个引用类型变量,只有它们指向同一个对象时,一判断才会返回true。注意:==不可用于比较类型上没有父子关系的两个对象

常量池

常量池(constant pool)专门用于管理在编译时被确定被保存在已编译的.class文件中的一些数据。它包括了关于方法接口中的常量,还包括字符串常量

常量池管理字符串的情形

Java程序直接使用形如"hello"的字符串直接量时,JVM将会使用常量池来管理这些字符串;当使用new String("hello")时,JVM会先使用常量池来管理"hello"直接量,再调用String类的构造器来创建一个新的String对象,新创建的String对象被保存在堆内存中。换句话说, new String("hello")一共产生了两个字符串对象
JVM常量池保证相同的字符串直接量只有一个,不会产生多个副本。

怎样的字符串可以在编译器确定

  1. 一条语句中只有字符串直接量的连接可以在编译时确定下来
  2. 字符串引用变量连接无法在编译时确定
  3. 字符串引用变量字符串直接量连接 也无法在编译时确定

字符串通过==运行符比较的情况

  1. 对应在编译期就可以确定下来的字符串直接量的引用变量,这些引用变量所引用的都是常量池中的同一个字符串对象。所以通过"=="运算符比较相等.
  2. 使用new String()创建的字符串对象是运行时创建出来的,该字符串对象被保存在运行时内存区,也就是保持在堆内存内,不会放入常量池中。所以两个通过new创建的字符串通过"=="比较将返回false

equals方法

equals方法是Object类提供的一个实例方法,因此所有引用变量都可调用该方法来判断是否与其他引用变量相等。

Object提供的equals方法只比较引用变量的地址是否一致

Object默认提供的equals()只是比较引用变量的地址是否一致,也就是说Object类的equals()方法比较的结果与”==“运算符比较的结果完全相同。

提供自定义的相等标准

如果希望采用自定义的相等标准,则可采用重写equals方法来实现。重写equals方法就是提供自定义的相等标准,你甚至可以让Person对象和Dog对象相等.

String重写的equals方法

String已经重写了Objectequals方法, Stringequals方法判断两个字符串相等的标准是:只要两个字符串所包含的字符序列相同,通过equals比较将返回true,否则将返回false

重写equals方法的条件

通常而言,正确地重写equals方法应该满足下列条件。

  1. 自反性:对任意x, x.equals(x)一定返回true
  2. 对称性:对任意xy,如果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. 一致性:对任意xy,如果对象中用于等价比较的信息没有改变,那么无论调用x.equals(y)多少次,返回的结果应该保持一致,要么一直是true,要么一直是false
  5. 对任何不是nullx,x.equals(null)一定返回false