Ase*_*sal 0 java inheritance overriding compilation execution
当继承和类型转换混合时,我有点困惑.我想了解java编译器在继承中选择正确的方法和变量时遵循的规则.
我读过类似的东西
变量在编译时绑定,并且方法在运行时绑定.
第二个来自stackoverflow(@John Skeet)
根据方法目标和参数表达式的编译时类型,在编译时确定重载分辨率(调用方法签名)
该方法签名(覆盖)的实现基于执行时目标对象的实际类型.
但问题在于它们是特定情况的解释,并且在考虑其他因素(例如异常处理)时不会给出一般过程.
这可能是不好的做法,但假设方法和变量都被覆盖(隐藏在static变量的情况下).
现在,如果java编译器必须在编译时选择需要调用哪个方法/变量,那么它将采用什么算法?类似地,在运行时,java编译器将使用什么算法(基于正在使用其引用的对象的实际类型)?
所有方法签名和变量都在编译期间进行验证,但实际的方法调用在运行时完成/解析.
例如 :
class A {
int i=5;
public void doSomething(){
//print "in A"
}
}
class B extends A{
int i=10;
public void doSomething(){
// print "in B"
}
public static void main(String[] args){
A a = new B();
a.doSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当您a.doSomething();在编译期间调用时,编译器只会检查是否doSomething()为类A定义(lhs引用).它甚至不关心该方法是否也为B类定义.即使该方法不存在B,该程序也可以正常编译.
接下来,在运行时,JVM根据Object的类型(B在您的情况下)动态地决定调用哪个方法.
所以,"in B"打印出来.
现在,回到田野.在编译期间解析对字段的访问.因此,如果在编译期间不存在某个字段,则编译将失败.根据引用类型调用字段.因此,a.i将打印5(A's值i)因为该字段在编译期间已解析.因此,不同之处在于,在运行时解析方法调用,在编译时需要/检查它们的签名,其中在编译时检查/解析字段.
| 归档时间: |
|
| 查看次数: |
1989 次 |
| 最近记录: |