编译和运行时类

时间:2012-11-01 13:41:42

标签: java

假设我有一个名为Person的类,它是另一个类Man的概括。如果我要做这个类的几个实例

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

现在,从变量man引用的实例的编译时类是Man,而编译时类的人是Person,而运行时类是两个实例都是Man。到目前为止,我完全使用术语,因为在运行时创建的实例都是类Man。但是,如果我在哪里施放man实例如下

Person personMan = (Person) man;

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

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

3 个答案:

答案 0 :(得分:5)

在此区分三种不同的概念非常重要:

  • 变量manperson
  • 引用(变量的值)
  • 对象(引用,嗯,引用的内存blob)

对象的类型在创建后永远不会更改。将引用转换为其他类型 only 会影响该表达式的编译时类型。引用类型强制转换表达式的结果始终与原始引用相同 - 它仍然引用相同的对象,该对象仍具有相同的类型。 (那就是把拳击放在一边 - 当然演员阵容可能会在执行时失败,导致例外。)

  

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

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

答案 1 :(得分:1)

运行时类型是新类型。新的Man()总是Man,无论你存储变量的类型如何。

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

在你的例子中

Person personMan = (Person) man;

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

((Man)personMan).someManMethod();

但如果personMap没有存储Man的实例,则会导致错误。

答案 2 :(得分:1)

在Java中,变量(基元除外)只是对象的引用。这些对象本身就存在于其他地方,永远无法直接访问。

在每种情况下,您都有一个Man对象,而不同的引用只能访问该Man对象功能的不同子集。