Har*_*nam 5 java performance equals referenceequals
在约书亚布洛赫的有效JAVA中,当我读到关于静态工厂方法时,有一个声明如下
静态工厂方法从重复调用返回同一对象的能力允许类在任何时候保持对存在的实例的严格控制.执行此操作的类称为实例控制.编写实例控制类有几个原因.实例控制允许类保证它是单例(第3项)或不可实例化(第4项).此外,它允许不可变类(第15项)保证不存在两个相等的实例:a.equals(b)当且仅当a == b时.如果一个类提供了这种保证,那么它的客户端可以使用==运算符而不是equals(Object)方法,这可以提高性能.枚举类型(第30项)提供此保证.
为了研究==运算符如何带来性能改进,我得看看 String.java
我看到了这个片段
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
通过性能提升,他的意思是什么?它如何带来性能提升.
他的意思是说以下内容
如果每个类都可以确保a.equals(b)当且仅当a == b时,这意味着它带来间接要求,即不能有对象引用2个不同的存储空间并且仍然保持相同的数据,即内存浪费.如果它们拥有相同的数据,则它们是同一个对象.这就是它们指向相同的内存位置.
我在这个推论中是对的吗?
如果我错了你可以指导我理解这个吗?
如果每个类都可以保证 a.equals(b) 当且仅当 a==b 时,这意味着它带来了一个间接要求,即不能有对象引用 2 个不同的内存空间,但仍然保存相同的数据,即内存浪费。如果它们保存相同的数据,那么它们就是同一个对象。也就是说,它们指向相同的内存位置。
是的,这就是作者的目的。
如果你可以(对于给定的类,这对所有类来说都是不可能的,特别是它不能用于可变类)调用==(这是单个 JVM 操作码)而不是equals(这是动态分派的方法调用),它可以节省(一些)开销。
enum例如,对于 s 来说,它就是这样工作的。
即使有人调用该equals方法(这将是很好的防御性编程实践,恕我直言,您不想养成使用==对象的习惯),该方法也可以实现为简单的==(而不是必须考虑潜在的复杂性)对象状态)。
顺便说一句,即使对于“普通”equals 方法(例如 String 的),在其实现中首先检查对象身份,然后快捷地查看对象状态可能是一个好主意(这就是 String#equals 所做的,就像您一样)已经发现了)。