编译器会优化未使用的私有方法吗?
问题描述:
如果javac内联了,私有方法是否会遗漏? 例如编译器会优化未使用的私有方法吗?
public class Test {
public static void main(String[] args){
System.out.println(sayHello());
}
private static String sayHello(){
return "Hello World";
}
}
但是,如果这种方法,然后通过反射访问呢?
System.out.println(Test.class.getMethod("sayHello").invoke(null));
编译器如何知道是否需要内联的方法,并删除它呢?
答
我按照用户的Jesper的建议,并使用javap的这个代码:
package *;
public class CompilerOptimize {
public static void main(String[] args){
System.out.println(sayHello());
}
private static String sayHello(){
return "Hello World";
}
private static void bananas() {
System.out.println("Monkey!");
}
}
方法sayHello
使用和bananas
不是。
上与Java 8编译的类-p参数运行的javap的结果是:
public class *.CompilerOptimize {
public *.CompilerOptimize();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: invokestatic #3 // Method sayHello:()Ljava/lang/String;
6: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
9: return
private static java.lang.String sayHello();
Code:
0: ldc #5 // String Hello World
2: areturn
private static void bananas();
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #6 // String Monkey!
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
方法bananas
在字节代码注释被提及(sayHello
是有太多)。
编译器会优化未使用的私有方法吗?
不是。
+1
@JB Nizet:对我很耻辱。非常感谢您指出缺少-p参数。你应该得到一些信用。 –
+0
感谢您的回答。我从来没有意识到,javac没有做任何优化!似乎错过了机会 – vikarjramun
是什么让你认为这个方法正在被编译器内联?它没有内联。内联可能发生在运行时,在JIT编译器中。 –
您可以通过使用'javap'反汇编编译的类来自己尝试一下。它很可能不会丢弃该方法。 – Jesper
编译器优化从不改变行为。 – 4castle