Java编译器(几乎)总是在编译时解析静态方法,这是一个普遍的事实。例如:
public class Super {
static void someMethod() {
// Do something...
}
}
public class Derived extends Super {
// Some other methods, excluding someMethod
}
测试代码:
Derived derived = new Derived();
derived.someMethod();
这应该调用Super.someMethod(),对吗?它应该在编译时解决,以便javac生成invokestatic Super.someMethod
,但我已经看到它生成invokestatic Derived.someMethod
。它为什么这样做?有没有办法以某种方式改变这种行为?
如果我错了,请纠正我。
答案 0 :(得分:4)
我们假设Super
和Derived
之间存在一个中间超类(称为Intermediate
)。
编译器生成Derived.someMethod
的原因是您可能会重新编译Intermediate
以插入someMethod
的实现,这会影响Super
的实现。
答案 1 :(得分:1)
记录:
public class TestSuperDerived {
public static void main(String[] argv) {
DerivedClass.someMethod();
}
}
class SuperClass {
static void someMethod() {
System.out.println("Here!");
}
}
class DerivedClass extends SuperClass {
// Some other methods, excluding someMethod
}
javap输出:
C:\JavaTools>javap -c TestSuperDerived
Compiled from "TestSuperDerived.java"
public class TestSuperDerived {
public TestSuperDerived();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: invokestatic #2 // Method DerivedClass.someMethod:()V
3: return
}