0

让我们想象一下我有一个名为的类Person,它是另一个类的泛化Man。如果我要制作这个类的几个实例

Man man = new Man();
Person person = new Man();

现在,从变量引用的实例的编译时类manMan,person 的编译时类是Person,而两个实例的运行时类是Man。到目前为止,我完全使用该术语,因为在运行时创建的实例都是 class Man。但是,如果我按如下方式将 man 实例投射到哪里

Person personMan = (Person) man;

为什么运行时类型personMan仍然是Man?实例的运行时类是否仅在创建新实例时设置?另外,有没有办法在运行时实际获取变量的编译时间类,所以我可以查询 personMan 是什么类型的类(getClass 会返回Man)。

编辑:“类的编译时类”是一个错误(并且没有多大意义)。我的意思是可变的(因此他们质疑 personMan 是什么类型的类:))

4

3 回答 3

5

在这里区分三个不同的概念很重要:

  • 变量( man, person)
  • 引用(变量的值)
  • 对象(引用的内存块,嗯,引用)

对象的类型在创建后永远不会改变。将引用转换为不同类型只会影响该表达式的编译时类型。引用类型转换表达式的结果始终与原始引用相同 - 它仍然引用同一个对象,该对象仍然具有相同的类型。(这将拳击放在一边——当然演员可能在执行时失败,导致异常。)

另外,有没有办法在运行时实际获取类的编译时类

如果您的意思是变量的编译时类型-不是局部变量,而无需真正深入检查字节码。如果它是一个领域,您可以使用反射来获得它。你为什么想知道?

于 2012-11-01T13:45:30.297 回答
1

运行时类型是新的类型。new Man() 始终是 Man,无论您存储它的变量的类型如何。

编译类型是声明变量的类型。

在你的例子中

Person personMan = (Person) man;

您只能使用 personMan 的方法和属性进行编码。你也可以做

((Man)personMan).someManMethod();

但是如果 personMap 没有存储 Man 的实例,这可能会导致错误。

于 2012-11-01T13:48:02.657 回答
1

在 Java 中,变量(除了原语)只是对对象的引用。对象本身存在于其他地方,永远无法直接访问。

在每种情况下,您都有一个Man对象位于某处,并且不同的引用只是提供对该Man对象功能的不同子集的访问。

于 2012-11-01T13:48:12.590 回答