2017-10-21 51 views
1

如果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)); 

编译器如何知道是否需要内联的方法,并删除它呢?

+3

是什么让你认为这个方法正在被编译器内联?它没有内联。内联可能发生在运行时,在JIT编译器中。 –

+1

您可以通过使用'javap'反汇编编译的类来自己尝试一下。它很可能不会丢弃该方法。 – Jesper

+1

编译器优化从不改变行为。 – 4castle

回答

2

我按照用户的Jesper的建议,并使用javap的这个代码:

package stackoverflow; 

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 stackoverflow.CompilerOptimize { 
    public stackoverflow.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