Search code examples
javajavaccompiler-optimizationprivate-methods

Will compilers optimize out unused private methods?


Does javac leave out private methods if they are inlined? For example

public class Test {
  public static void main(String[] args){
    System.out.println(sayHello());
  }
  private static String sayHello(){
    return "Hello World";
  }
}

But what if this method is then accessed by reflection?

 System.out.println(Test.class.getMethod("sayHello").invoke(null));

How does the compiler know whether to inline the method and remove it or not?


Solution

  • I have followed user Jesper's suggestion and used javap on this code:

    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!");
        }
    }
    

    Method sayHello is used and bananas is not.

    The result of running javap with the -p parameter on the compiled class with Java 8 is:

    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
    }
    

    The method bananas is mentioned in the byte code comments (sayHello is there too).

    Will compilers optimize out unused private methods?

    Not really.