我不确定作者写单例静态工厂方法是否可以保证不存在两个相等的实例时的含义。好吧,实际上我确实理解了这一点,但是当他演示equals方法与文字比较运算符时,我对以下文本感到困惑:“ a.equals(b)仅当a == b时。”
我知道equals()
方法实际上是比较对象的内容,而文字==
是比较以查看它们是否是内存中的同一对象。这令人困惑,因为他继续说客户端可以使用==
而不是.equals(object)
方法。为何如此?如果保证只对一个对象,客户端为什么要使用==
比较器?
有人可以给我写一个简短的代码示例来更具体地解释这一点吗?
作者的文字如下:
静态工厂方法从中返回相同对象的能力
重复调用使类可以保持对
任何时候都存在哪些实例。据说这样做的班级是
实例控制。有几个原因写
实例控制的类。实例控件允许类
确保它是单例(项目3)或非实例化(项目4)。
而且,它允许不可变的类(第15项)做出保证
没有两个相等的实例存在:a.equals(b)当且仅当a == b。如果
一个类可以保证这一点,那么它的客户可以使用==运算符
而不是equals(Object)方法,这可能会改善
性能。枚举类型(项30)提供了此保证。
最佳答案
我想你已经快知道了。静态方法做出了以下承诺:“如果您请求将.equals()与现有对象进行比较的新对象,我将改为返回现有对象”。有了这个保证,您就知道a.equals(b)
表示a == b
,并且您知道a == b
表示a.equals(b)
。结果,如果要查看a
和b
是否相等,则可以使用==
运算符而不是.equals
方法。这很有用,因为==
非常快,并且根据对象类型,.equals
可能很慢。
这是一个具体的例子。假设我们有一个人类。一个人是由他们的名字和姓氏定义的(假设世界上没有两个人具有相同的名字)。我的类可能看起来像这样(未尝试编译,因此不能保证正确性):
class Person {
private final String fname;
private final String lname;
// Private constructor - must use the static method
private Person(String first, String last) {fname = first; lname = last;}
// Note that this is slow - the time it takes is proportional to the length of the
// two names
public boolean equals(Object o) {
// Should check types here, etc.
Person other = (Person) o;
if (!person.fname.equals(other.fname)) {return false;}
if (!person.lname.equals(other.lname)) {return false;}
return true;
}
// Registry of all existing people
private static Map<String, Person> registry = new TreeMap<String, Person>();
public static getPerson(String fname, String lname) {
String fullName = fname + "-" + lname;
// If we already have this person, return that object, don't construct a new one.
// This ensures that p1.equals(p2) means that p1 == p2
if (registry.containsKey(fullName)) {return registry.get(fullName);}
Person p = new Person(fname, lname);
registry.put(fullName, p);
return p;
}
}
然后可以像这样使用它:
public boolean isSamePerson(Person p1, Person p2) {
// Guaranteed to have the same result as "return p1.equals(p2)" but will be faster
return p1 == p2;
}
关于java - 关于有效Java文本的困惑,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20846891/