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
常量池保证相同的字符串直接量
只有一个,不会产生多个副本。
怎样的字符串可以在编译器确定
- 一条语句中只有
字符串直接量的连接
可以在编译时确定下来 字符串引用变量
的连接
无法在编译时确定字符串引用变量
和字符串直接量
的连接
也无法在编译时确定
字符串通过==运行符比较的情况
- 对应在编译期就可以确定下来的
字符串直接量
的引用变量,这些引用变量所引用的都是常量池中的同一个字符串对象
。所以通过"=="
运算符比较相等. - 使用
new String()
创建的字符串对象是运行时
创建出来的,该字符串对象被保存在运行时内存区
,也就是保持在堆内存内
,不会放入常量池中
。所以两个通过new
创建的字符串通过"=="
比较将返回false
。
equals方法
equals
方法是Object
类提供的一个实例方法,因此所有引用变量都可调用该方法来判断是否与其他引用变量相等。
Object提供的equals方法只比较引用变量的地址是否一致
Object
默认提供的equals()
只是比较引用变量的地址是否一致,也就是说Object
类的equals()
方法比较的结果与”==
“运算符比较的结果完全相同。
提供自定义的相等标准
如果希望采用自定义的相等标准,则可采用重写equals
方法来实现。重写equals
方法就是提供自定义的相等标准,你甚至可以让Person
对象和Dog
对象相等.
String重写的equals方法
String
已经重写了Object
的equals
方法, String
的equals
方法判断两个字符串相等的标准是:只要两个字符串所包含的字符序列相同,通过equals
比较将返回true
,否则将返回false
重写equals方法的条件
通常而言,正确地重写equals
方法应该满足下列条件。
- 自反性:对任意
x
,x.equals(x)
一定返回true
- 对称性:对任意
x
和y
,如果y.equals(x)
返回true
,则x.equals(y)
也返回true
- 传递性:对任意
x,y,z
,如果x.equals(y)
返回true
,y.equals(z)
返回true
,则x.equals(z)
一定返回true
。 - 一致性:对任意
x
和y
,如果对象中用于等价比较的信息没有改变,那么无论调用x.equals(y)
多少次,返回的结果应该保持一致,要么一直是true
,要么一直是false
- 对任何不是
null
的x
,x.equals(null)
一定返回false
原文链接: 6.2.2 ==和equals方法