3

我有一个名为的类Entity,它是abstract我在整个程序中使用的许多其他对象的超类(对于这个例子,Apple类)。

在许多方法中,我打印调试语句,方法是打印语句所在的类名,然后是实际的调试消息。然而,令我惊讶的是,当我从 的实例调用继承的方法时AppleApple打印的是 的类名而不是 的类名Entity(这是方法实际所在的位置)。

举一个更容易发布代码片段的相关示例,我已经toString()像这样覆盖:

public abstract class Entity {

    private String name;

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

因为我没有在Apple类中进一步重写这个方法,所以我希望返回的 String 的第一部分是Entity,而不是Apple。然而它却返回了Apple(对于这个用例,它以这种方式工作实际上很好,但仍然有些令人困惑)。

我尝试查看 的实现Object#getClass(),但由于它被声明为native方法而无法查看。

public final native Class<?> getClass();

谁能解释为什么会这样?

4

1 回答 1

7

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

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

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

您无需查看实现-getClass()只需查看文档

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

请注意“运行时”位,如“在执行时确定,而不是在编译时确定”。

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

于 2013-02-20T17:16:15.547 回答