Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is constructor generated default constructor?

Is there a way to find out by reflection whether a constructor is a compiler generated default constructor or not? Or is there some other way?

Surprisingly the isSynthetic method does not give this information so it can't be used. And there is no Generated annotation present.

public class JavaTest {
    public void run() throws Exception {
        out.println(JavaTest.class.getConstructors()[0].isSynthetic()); // Prints false
        out.println(Arrays.asList(JavaTest.class.getConstructors()[0].getAnnotations())); // Prints []
    }
}

This question asks the same thing but for C#: Detect compiler generated default constructor using reflection in C#

like image 542
Lii Avatar asked Jul 12 '13 15:07

Lii


1 Answers

No, the compiler generates them:

I created the file A.java:

public class A{
public String t(){return "";}
}

then:

javac A.java

and running javap -c A to see the content:

Compiled from "A.java"
public class A {
  public A();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return        

  public java.lang.String t();
    Code:
       0: ldc           #2                  // String 
       2: areturn       
}

if I add the constructor:

public A(){}

the result is:

Compiled from "A.java"
public class A {
  public A();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return        

  public java.lang.String t();
    Code:
       0: ldc           #2                  // String 
       2: areturn       
}

it's identical. I'm using Java 7 with 64 bit OpenJDK, but I'd bet that it's the same with all the versions.

EDIT: in fact, the same bytecode alone doesn't guarantee that the information is not present as metadata. Using an hex editor and this program was possible to see that there are two bytes differing, and correspond to the line numbers (used for printing stack traces), so the information is absent in this case.

like image 56
Jacopofar Avatar answered Oct 08 '22 06:10

Jacopofar