- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
首先,我并不是询问它们之间的区别。
我心里有一个想法,我想要更多的大脑来验证,这似乎能够发挥(大部分)使用这两种方法的优点。
简而言之,Java 中的 equals()
通常如下所示。
public boolean equals(Object other) {
if (other == null) return false;
if (this == other) return true;
if (this and other is not of the same type) return false
// then actual equals checking
}
问题在于“这个和其他不是同一类型”检查。
有一类人更喜欢使用if (!(other instanceof MyClass))
,它有一个缺点
MyClass
的子类并且重写了 equals()
、a.equals(b)
和 b.equals(a )
不会相同equals()
另一类人更喜欢使用if (getClass() != other.getClass())
,它有一个缺点
MyClass
的子类应该能够代替 MyClass
使用。a
属于 MyClass
而 b
属于MyClass
的子类,连内部属性都一样。我心中有一个想法,希望人们验证。
这种方法应该
equals()
,结果仍应是对称的子类仍然可以用作其父类型(在 equals()
方面,并且 equals
当然不会被覆盖)
public class Parent {
@Override
public boolean equals(Object other) {
if (other == null) return false;
if (this == other) return true;
if (!(other instanceof Parent)) return false;
try {
if (other.getClass().getMethod("equals", Object.class).getDeclaringClass() != Parent.class) {
return other.equals(this);
}
} catch(Exception neverHappen){}
// do actual checking
}
}
主要思想是,如果this
遇到一个Parent
对象,但该对象的equals()
未在Parent中声明
(即该对象是一个子类,并覆盖了 equals()
,我将把 equals
调用委托(delegate)给子类对象(或者可能只是返回 false )。
使用这种方法是否有任何我忽略的缺点? (我猜性能损失将是一个问题,但我相信调用 getClass().method("equals").getDeclaringClass()
应该相当便宜?)
最佳答案
正如评论中所述,如果子类这样做 super.equals(..)
,你会得到一个 stackoverflow。为了防止这种情况,你最终会重写整个 parent equals(..)
在每个 child 身上,这是最糟糕的设计。
不知何故,这取决于您首先如何/为何实现继承。 child 应该与 parent 相媲美吗?比较有意义吗? (已编辑)
如果您覆盖 equals,那么根据定义,您就不尊重 LSP。如果子级有更多参数(这意味着它覆盖了 equals 方法),那么它不应该等于其父级,这就是为什么我们可以使用 getClass() != other.getClass()
进行比较在父级中。如果想使用父类的equals()
在你的 child 中(所以你不必全部重写),你不会最终出现堆栈溢出; equals()
只会是错误的,因为它们本来就不是平等的。
如果一个 child 与其 parent 具有可比性怎么办?如果您尊重 LSP, child 就不应该有不同的equals()
我猜比他的 parent (即: equals 不应该被覆盖)。所以不对称的情况不应该存在。
如果一个 child 与其 parent 相当,但有更多参数?现在这是您的设计,不尊重 LSP,因此您需要了解它在您的上下文中的含义并采取相应的行动。
<小时/>编辑:@Adrian 是的,“对称性有意义吗”是糟糕的措辞,我应该说“比较有意义吗?”。
对于您的示例,如果您将两个子类与 getClass()
进行比较他们还使用 super getClass()
它将返回 true (测试将是重复的,因为 this.getClass()
和 other.getClass()
在子级和父级中始终具有相同的值)。但正如我所说,如果你比较 child 和 parent ,那将是错误的(我认为如果他们有不同的参数,这是正常的)。
为什么仅在 equals 和 of 的实例上使用final?你这么说是因为可能存在不对称,而使用 getClass()
继承是不可能不对称的。 ,所以在这种情况下将其定为最终版本是没有用的。
作为旁注,如果您使用 getClass()
,那么同一父级的多个子级将不具有可比性(始终返回 false )。如果您使用instanceof
,他们可以,但如果他们这样做,任何 child 都不应覆盖 equals()
因为有破坏对称性的风险。 (我想你明白了,但我想知道什么时候选择 insteanceof
而不是 getClass()
如果它有问题的话)。
关于equals() 中的 Java 类型检查 : instanceof vs getClass(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39766245/
为什么这在 Java 中可行: this.getClass().getClass().getClass().getClass()... 为什么会出现这种无限递归? 只是好奇。 最佳答案 这里没有无限递
我正在测试Object是否等于特定的class类型。例如: @Override public void itemStateChanged(ItemEvent e) { if (e.getSta
详解java中this.getClass()和super.getClass()的实例 前言: 遇到this.getClass()和super.getClass()的返回值感到疑惑,经过探索豁然开
Blockquote public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == nul
我正在尝试比较两个相同的对象。当页面第一次加载时,它们是相等的,但是当我第二次刷新页面时,尽管数据或对象没有改变,但它们并不相等。 我在做什么。 我有一个 CurrentUser obj,我在登录时将
我的 MyClass 类中有 equals() 的 @Override: @Entity( name = "MyClass" ) @Table( name = "my_class" ) public
我在这里真的是指身份平等。 例如,以下是否总是打印 true? System.out.println("foo".getClass() == "fum".getClass()); 最佳答案 是的,类标
getClass().getClassLoader().getResource()和getClass.getResource()有什么区别? 从资源中检索文件时,在什么情况下应该使用哪一个? 最佳答案
这个问题已经有答案了: Different ways of loading a file as an InputStream (6 个回答) 已关闭 5 年前。 我正在浏览 ImageIO,并且在网络
有没有办法创建另一个对象类型的新对象? 示例: Soldier extends Person Accountant extends Person Person 的每个子类都有一个接受(出生日期和死亡日
FXMLLoader类的 load()方法用于加载FXML文件。那么 getClass().getResource() 是在做什么 Parent root = FXMLLoader.load(getC
考虑这段代码: class A { static int i=3; } public class TT extends A { public static void main(Stri
为什么第一行有效而第二行无效: Class c1 = (new Object()).getClass().getClass(); Class> c2 = (new O
我见过类似的问题并且有一个可行的解决方案,但我没有深入理解为什么我的示例中的前四次尝试(c1、c2、c3 和 c4)无法编译。归结为我不理解 this.getClass() 返回的编译时类是什么。 i
这个 Actor 安全吗? private void foo(T value) { final Class aClass = (Class) value.getClass(); } 是否存在
我在学习 Java 时遇到了一件奇怪的事情。考虑以下程序: public class GetClassNameInheritance { public static void main(Str
我编写了以下代码: public class AnonymousClasses { public void sayHello(){ } public interface Greetin
我正在尝试创建其中包含文本字段的对话框。代码如下 private void showBatchDialog() { Dialog dialog = new Dialog(); dial
我正在尝试使用 getClass() 方法并具有以下代码: class parent{} class child extends parent{} public class test { pu
在 Java 中,我想为方法编写测试(简化片段): public class MyClass { private static final Set SOME_SET = new HashSet
我是一名优秀的程序员,十分优秀!