反汇编以下文件(带有javap -c
)表明它们在编译为字节码时不会被 1.7.0 编译器剥离:
public class Program
{
public static class Message extends Object {}
public interface ILogger {
void log(Message m);
}
public static class Logger implements ILogger {
public void log(Message m) { /* empty */ }
}
public static void main(String[] args) {
ILogger l = new Logger();
l.log((Message)null); // a)
l.log(new Message()); // b)
}
}
结果如下。关键位是第 13 行和第 26 行的调用。
Compiled from "Program.java"
public class Program {
public Program();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2 // class Program$Logger
3: dup
4: invokespecial #3 // Method Program$Logger."<init>":()V
7: astore_1
8: aload_1
9: aconst_null
10: checkcast #4 // class Program$Message
13: invokeinterface #5, 2 // InterfaceMethod Program$ILogger.log:(LProgram$Message;)V
18: aload_1
19: new #4 // class Program$Message
22: dup
23: invokespecial #6 // Method Program$Message."<init>":()V
26: invokeinterface #5, 2 // InterfaceMethod Program$ILogger.log:(LProgram$Message;)V
31: return
}
编辑:但是,正如@mikera 指出的那样,JIT 编译器可能会在程序运行时进行进一步优化,这可能能够消除调用。不幸的是,我对细节知之甚少,无法对此发表评论。
旁注:您可能对此链接感兴趣,该链接涉及 Hotspot JVM 使用的性能技术:
https://wikis.oracle.com/display/HotSpotInternals/PerformanceTechniques