为什么在父类方法中返回子类名称?

3
我有一个名为“Entity”的类,它是我在程序中使用的许多其他对象(例如“Apple”类)的抽象超类。
在许多方法中,我通过先打印语句所在的类名,然后再打印实际的调试信息来打印调试语句。但令我惊讶的是,当我从“Apple”类的实例中调用继承的方法时,打印的是“Apple”的类名,而不是实际位于“Entity”中的方法的类名。
以一个更容易发布代码片段的相关示例为例,我已按以下方式重写了“toString()”:
public abstract class Entity {

    private String name;

    @Override
    public String toString() {
        return getClass().getSimpleName() + " " + (name != null ? name : super.hashCode());
    }
}

因为我没有在Apple类中进一步覆盖此方法,所以我希望返回的字符串的第一部分是Entity,而不是Apple。然而它返回了Apple(这实际上对于这种用例很好,但仍然有些令人困惑)。
我尝试查看Object#getClass()的实现,但由于它被声明为native方法,所以无法查看其实现。
可以有人解释一下为什么会发生这种情况吗?
1个回答

7

你正在调用getClass()。它总是返回与对象的实际执行时类型相关联的Class对象的引用,而不是你在其上调用它的表达式的编译时类型的类。例如:

Object foo = "this is a string";
Class<?> clazz = foo.getClass();

clazz 将引用 String 类的类,而不是 Object 的类。

你不需要查看 getClass() 的实现 - 只需查看 文档

表示此对象的运行时类的 Class 对象。

请注意“运行时”这一点,即“在执行时确定,而不是在编译时确定”。

在这种情况下,我认为在 toString() 的结果中返回执行时类名是完全合理的,但如果你真的非常想要 Entity 类,你可以使用 Entity.class 代替。


谢谢你的回答。是的,toString()这样工作确实很好,但有时在调试时会令人沮丧。 :) 而且一开始它违背了我的语言预期。 - asteri

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接