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#
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With