当继承与类型转换混合在一起时,我有点困惑。我想了解在继承中选择正确的方法和变量时java编译器遵循的规则。
我读过类似的东西
变量在编译时绑定,方法在运行时绑定。 重载分辨率 (称为方法签名)是在编译时根据方法目标和参数表达式的编译时类型确定的 该方法签名( 覆盖 )的实现基于执行时目标对象的实际类型。
变量在编译时绑定,方法在运行时绑定。
重载分辨率 (称为方法签名)是在编译时根据方法目标和参数表达式的编译时类型确定的
该方法签名( 覆盖 )的实现基于执行时目标对象的实际类型。
但是问题在于它们只是对特定情况的解释,没有考虑其他因素(例如异常处理)时要遵循的一般过程。
这可能是不好的作法,但假设方法和变量都被覆盖(在static变量的情况下被隐藏)。
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(); } }
现在,当您调用时a.doSomething();,在编译过程中,编译器仅检查是否doSomething()为类A定义了(lhs参考)。甚至不必担心是否也为类B定义了该方法。即使该方法不存在B,该程序也可以正常编译。
a.doSomething();
doSomething()
B
接下来,在运行时,JVM根据对象的类型(B根据您的情况)动态决定要调用的方法。
因此,"in B"被打印。
"in B"
现在,回到领域。在编译期间将解决对字段的访问。因此,如果在编译期间不存在任何字段,则编译将失败。这些字段根据引用类型进行调用。因此,a.i将打印5(A's值i),因为该字段在编译时已解决。因此,不同之处在于,方法调用在运行时解析,在编译时需要/检查其签名,而在编译时则检查/解析字段。
a.i
5
A's
i