【发布时间】:2013-08-11 11:59:11
【问题描述】:
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。为什么要这样做?有没有办法以某种方式改变这种行为?
如果我错了,请纠正我。
【问题讨论】:
-
javac 编译器在编译时解析所有 方法引用,以查找方法并检查其签名。然而,当类被 JVM 加载或第一次调用时,方法的实际“绑定”就完成了。
-
(为什么要改变行为?它的工作方式非常有用。)
-
您的代码甚至无法编译。你是怎么得到那个字节码的?
-
我已经编辑了代码以反映我对 OP 意图的解释。如果一个类实际上不是从任何东西派生的,那么将其称为“派生”是没有意义的。 @kabbi,请贴出可以编译的代码,以免造成误解。
-
需要注意的是,使用实例调用静态方法是javac的“swizzle”,它与Java的工作方式没有真正的关系,而纯粹是一种“方便”。编码
SomeClass someRef = new SomeClass(); someRef.someStaticMethod();完全等同于编码SomeClass.someStaticMethod();。这与继承无关。
标签: java inheritance static-methods