Is constructor generated default constructor?

后端 未结 2 1557
一向
一向 2021-02-19 04:52

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 isS

相关标签:
2条回答
  • 2021-02-19 05:33

    No, there is no metadata in the bytecode that would allow you to distinguish a compiler generated default constructor from a non-generated one.

    In most cases, compiler generated constructors and methods are marked with the ACC_SYNTHETIC flag or the Synthetic attribute in the generated bytecode. However, there are a few notable exceptions as per 13.1 item 7 from the Java Language Spec and 4.7.8 from the jvm-spec

    Here is the relevant bit from the JLS:

    Any constructs introduced by a Java compiler that do not have a corresponding construct in the source code must be marked as synthetic, except for default constructors, the class initialization method, and the values and valueOf methods of the Enum class

    As far as I know, javap does not show the ACC_SYNTHETIC flag but you would be able to read it through isSynthetic if it was set.

    0 讨论(0)
  • 2021-02-19 05:38

    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.

    0 讨论(0)
提交回复
热议问题