Java 编译和运行时类
假设我有一个名为Java 编译和运行时类,java,Java,假设我有一个名为Person的类,它是另一个类Man的泛化。如果我要制作这个类的几个实例 Man man = new Man(); Person person = new Man(); 现在,从变量man引用的实例的编译时类是man,person的编译时类是person,而两个实例的运行时类都是man。到目前为止,我完全理解这个术语,因为在运行时创建的实例都属于类Man。但是,如果我把这个男人的例子放在哪里,如下所示 Person personMan = (Person) man; 为什么运
Person
的类,它是另一个类Man
的泛化。如果我要制作这个类的几个实例
Man man = new Man();
Person person = new Man();
现在,从变量man
引用的实例的编译时类是man
,person的编译时类是person
,而两个实例的运行时类都是man
。到目前为止,我完全理解这个术语,因为在运行时创建的实例都属于类Man
。但是,如果我把这个男人的例子放在哪里,如下所示
Person personMan = (Person) man;
为什么运行时类型的personMan
仍然是Man?实例的运行时类是否仅在创建新实例时设置?另外,是否有一种方法可以在运行时实际获取变量的编译时类,这样我就可以查询personMan是什么类型的类(getClass将返回Man
)
编辑:“类的编译时类”是一个错误(并且没有多大意义)。我的意思是可变的(因此他们质疑personMan是什么类型的阶级:)这里区分三个不同的概念很重要:
- 变量(
,man
)person
- 引用(变量的值)
- 对象(引用的内存块,嗯,引用的)
如果您指的是一个变量的编译时类型——如果它是一个局部变量,则不需要对字节码进行真正深入的检查。如果它是一个领域,你可以使用反射得到它。您为什么想知道?运行时类型是新的类型。new Man()始终是Man,无论变量的类型存储在何处 编译类型是声明变量的类型 在你的例子中
Person personMan = (Person) man;
您只能使用personMan的方法和属性进行编码。你也可以
((Man)personMan).someManMethod();
但是如果personMap没有存储Man的实例,这可能会导致错误。在Java中,变量(而不是原语)只是对对象的引用。这些对象本身生活在其他地方,永远无法直接访问
在每种情况下,您都有一个
Man
对象位于某个位置,而不同的引用只允许访问该Man
对象功能的不同子集。好的,谢谢您的回答。我问的原因仅仅是出于好奇:)