java - 对象的等于方法?
问题描述
谁能解释为什么第一个代码等于 false 而第二个代码等于 true?
解决方案
equals(Object)
Java 中的所有对象都以基Object
类中的方法开头。您的第二个示例简单地覆盖了此方法,因此无论何时equals(Object)
调用该方法,都会使用覆盖实现而不是基本实现。
但是,在您的第一个示例中,您为该方法添加了一个新equals()
的重载,其参数列表与基于的Object.equals()
方法不同。当这两个都为真时,任何时候调用它都会使用这个重载:
- 用于调用该方法的引用具有编译时类型
Circle
, 和 - 传递给方法的参数的编译时类型为
Circle
第一个条件是必需的,以便编译器可以首先找到该方法。如果调用的目标实例的编译时类型不是Circle
,那么equals(Circle)
甚至不会考虑方法的重载。
第二个条件是必需的,以便编译器可以将equals(Circle)
重载识别为要调用的重载。如果在编译时不知道要传递的参数是Circle
,那么编译器就不能安全地使用该equals(Circle)
方法,而必须选择equals(Object)
重载。
在您的第一个示例中,方法调用的目标实例以及传递给方法的参数的编译时类型是 isObject
和 not Circle
。因此,编译器没有安全的方法来调用equals(Circle)
重载,而必须调用equals(Object)
. 并且那个重载,基本实现,只是比较两个对象的引用,true
只有当它们相同时才返回(在这种情况下,作为两个不同的实例,显然不是)。
顺便说一句:第二个实现不太正确,因为它假设circle
传入的参数始终是 type Circle
。这在您问题的退化代码示例中是正确的,但在现实世界的程序中通常不是这样。正确的实现会首先检查参数的类型,如果类型不正确则equals(Object)
立即返回。false
推荐阅读
- cassandra - fsync 提交日志延迟的原因
- .htaccess - .htaccess 重写包含下划线和参数的孤立 URL
- ajax - AJAX 代码仅在 iPad 上不起作用
- macos - 使用 cmake 构建 macos 框架时如何指定 (Un)Exported Symbols 文件?
- java - JPA 应用程序中的 Persistence.createEntityManagerFactory 错误
- uml - 用例图逻辑
- c# - 创建/托管类库以供跨应用程序使用的选项?
- caching - 跟踪 Google Cloud CDN 缓存命中率
- f# - F# - 将 Deedle FrameData 写入 CSV
- scala - 无法用 lambda 覆盖 scala 抽象函数