假设我有一个名为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
)。
编辑:“类的编译时类”是一个错误(并没有多大意义)。我的意思是变量(因此他们质疑人类的类型是什么类型:))
答案 0 :(得分:5)
在此区分三种不同的概念非常重要:
man
,person
)对象的类型在创建后永远不会更改。将引用转换为其他类型 only 会影响该表达式的编译时类型。引用类型强制转换表达式的结果始终与原始引用相同 - 它仍然引用相同的对象,该对象仍具有相同的类型。 (那就是把拳击放在一边 - 当然演员阵容可能会在执行时失败,导致例外。)
另外,有没有办法在运行时实际获取类的编译时类
如果你的意思是变量的编译时类型 - 不是它是一个局部变量,而没有真正深入检查字节代码。如果它是字段,您可以使用反射来获取它。你为什么想知道?
答案 1 :(得分:1)
运行时类型是新类型。新的Man()总是Man,无论你存储变量的类型如何。
编译类型是声明变量的类型。
在你的例子中
Person personMan = (Person) man;
您只能使用personMan的方法和属性进行编码。你也可以
((Man)personMan).someManMethod();
但如果personMap没有存储Man的实例,则会导致错误。
答案 2 :(得分:1)
在Java中,变量(基元除外)只是对象的引用。这些对象本身就存在于其他地方,永远无法直接访问。
在每种情况下,您都有一个Man
对象,而不同的引用只能访问该Man
对象功能的不同子集。