Java Synthetic Class, Method, Field

Class, method, field and any other similar constructs introduced by java compiler are called synthetic. It may not be directly visible in the java source code.
Java synthetic classes, methods and fields are for java runtime’s internal purposes. We may not need to have knowledge about them to write the code.

Uses of Java Synthetic

  • It might be useful in debugging sessions, when we see those synthetic stuff in stack trace we can understand what it is.
  • AOP, generics, enums uses Java synthetic.
  • Java reflection API exposes method to check if an element is synthetic.
  • A regular java application programmer will not require synthetic for day to day programming.
  • This knowledge may be required in interviews but that doesn’t mandate that you will use it in the project.

When synthetic is created?

When an enclosing class accesses a private attribute of a nested class, Java compiler creates synthetic method for that attribute. If there is a getter method available in source then this synthetic method will not be created.
Similarly for constructor of inner classes also synthetic is created. There are many occasions, like this where a synthetic field or method or class is created.
When a default constructor is not available it is created by the Java compiler, but this generated constructor does not qualify as synthetic as per spec. Refer bug.
So what does Java Virtual Machine Specification (SE7) says about synthetic,
A class member that does not appear in the source code must be marked using a Synthetic attribute, or else it must have its ACC_SYNTHETIC flag set. The only exceptions to this requirement are compiler-generated methods which are not considered implementation artifacts, namely the instance initialization method representing a default constructor of the Java programming language (§2.9), the class initialization method (§2.9), and the Enum.values() and Enum.valueOf() methods..
Java bridge method is a synthetic method created during type erasure. Let us see see about bridge method is a detailed separate article.

Sample Program

In the following program, we have a nested class with a private attribute and it we have not give a getter method. We access that directly from the enclosing class. Java compiler introduces a getter method on compilation.
We have used reflection to list all the methods of the nested class and checking if they are synthetic. We get the generated method listed and isSynthetic returns true.
 
package java;
 
import java.lang.reflect.Method;
 
public class SyntheticSample {
 
  public static void main(String args[]) {
 
    SampleNestedClass nestObj = new SampleNestedClass();
    System.out.println("Nested Variable: " + nestObj.aPrivateVariable);
 
    Class c = nestObj.getClass();
    Method[] methods = c.getDeclaredMethods();
 
    for (Method m : methods) {
      System.out
          .println("m: " + m + " m.isSynthetic: " + m.isSynthetic());
    }
 
  }
 
  private static final class SampleNestedClass {
    private String aPrivateVariable = "A Private Variable!";
 
  }
 
}

OUTPUT:
Nested Variable: A Private Variable!
m: static java.lang.String java.SyntheticSample$SampleNestedClass.access$1(java.SyntheticSample$SampleNestedClass) m.isSynthetic: true

Use javap to analyze the class file generated:

D:\hareesh\eclipseworkspace\JP Programs\bin>javap java\SyntheticSample.SampleNestedClass
JAVAP OUTPUT:
Compiled from "SyntheticSample.java"
final class java.SyntheticSample$SampleNestedClass extends java.lang.Object{
    java.SyntheticSample$SampleNestedClass(java.SyntheticSample$SampleNestedClass);
   static java.lang.String access$1(java.SyntheticSample$SampleNestedClass); }
access$1 is a java compiler generated getter-method.

0 comments:

Post a Comment