我是Java的新手,正在读一本Java书;有一次它讨论了你何时想要覆盖内置函数equals()。例如,如果一个对象具有一个变量ID,并且两个对象具有相同的ID,那么您可能希望它们被认为是相等的。它提供了看起来或多或少的示例代码:
public boolean equals(Object obj) {
if((obj != null) && (obj instanceof myClass)) {
myClass object1 = (myClass)obj;
if(this.ID == object1.ID) {
return true;
}
}
return false;
}
我不完全理解第三行中发生了什么。我不确定为什么它是必要的,你不能只在if()语句中比较obj.ID和this.ID。我的猜测是,因为obj只是被声明为一个通用对象,可能没有ID,所以你需要创建一个新对象,object1,它是正确的类来查看ID。
我在这里纠正吗?究竟是怎么回事?
答案 0 :(得分:4)
在您的代码中,Object obj
是对象的引用。此时的代码不会假设它是哪种类型的对象。
当你这样做时
myClass object1 = (myClass) obj;
您正在将引用的类型转换为对象,这将成功,因为它是该类型的实例或者无法抛出ClassCastException。
这会创建一个新的引用,但基础对象不会被更改,也不会被复制。
注意:obj != null
检查是多余的,因为null
不是任何类的instanceof
,也不会触发异常。即。
Object o = null;
boolean b = o instanceof Object; // always false, never throws an exception.
此方法的较短版本可以阅读。
public boolean equals(Object obj) {
if(obj instanceof myClass) {
myClass object1 = (myClass)obj;
return ID == object1.ID;
}
return false;
}
甚至
public boolean equals(Object obj) {
return obj instanceof myClass && ID == ((myClass) obj).ID;
}
在Java 8中,您可以编写
public boolean equals(Object obj) {
return Optional.ofNullable(obj)
.filter(o - > o instanceof myClass)
.map(o -> (myClass) o)
.filter(m -> ID == m.ID)
.isPresent();
}
答案 1 :(得分:1)
在第3行,没有创建任何对象。
你需要了解的第一件事就是有{em>原语,如int
,char
,double
和对象,这是其他所有内容,对象总是通过引用访问。
因此,Object obj
是对Object
类型对象的引用,在运行时它将引用某个对象。
然后,再往下,当你说myClass object1
你没有创造任何物体时;您只是声明一个名为object1
的变量,它将引用myClass
类型的对象。但是还没有任何对象。
因此,当您说myClass object1 = (myClass)obj;
时,您要将参考obj
分配给参考object1
。由于在不同类型之间进行赋值通常无效,因此您使用类型转换((myClass)
部分)告诉编译器您知道自己在做什么,并且您确定obj
将指向此处myClass
类型的对象。因此,编译器允许您进行分配。
分配后,obj
和object1
都指向同一个对象,但object1
现在的用处是可以将此对象视为{{{ 1}},以便您可以访问其成员。
答案 2 :(得分:0)
是。第三行是在一个if语句中,它表示obj instanceof myClass。那时你知道它是myClass类型。假设myClass在您的代码中有一个ID,那么您就知道这两个对象都具有ID属性,您可以将它们用于比较。
答案 3 :(得分:0)
研究术语“对象强制转换”。
obj instanceof myClass
确保obj
与this
的类型相同。现在我们知道将Object obj
投射到myClass object1
答案 4 :(得分:0)
不需要null
的测试,因为instanceof
false
为null
。
只需使用:
if (obj instanceof myClass) {
否则,您的代码没问题,假设ID
是原始代码(尤其是String
)。
答案 5 :(得分:0)
您的猜测几乎正确:=Iif(Fields!Description.Value="Sub Total", "Solid","None")
声明类型为obj
,Object
可以是任何内容,例如Object
,它不必拥有成员名为String
,所以,你不能只看它来比较。所以,你引用的代码首先检查ID
是否属于同一类型(如果不是,那么你知道它不相等),然后(在你要问的那一行)将转换为该类型。
我说,你的猜测几乎正确,因为你建议创建一个obj
类型的新对象。这不是真的。赋值myClass
不会创建任何新对象,它只会使新变量myClass object1 = (myClass)obj;
引用object1
引用的同一对象,并告诉编译器它现在应该知道该对象实际上是obj
类型。