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.

synthetic_insert

Uses of Java Synthetic

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 com.javapapers.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 com.javapapers.java.SyntheticSample$SampleNestedClass.access$1(com.javapapers.java.SyntheticSample$SampleNestedClass) m.isSynthetic: true

Use javap to analyze the class file generated:

D:\joe\javapapers\eclipseworkspace\JP Programs\bin>javap com\javapapers\java\SyntheticSample.SampleNestedClass

JAVAP OUTPUT:

Compiled from "SyntheticSample.java"
final class com.javapapers.java.SyntheticSample$SampleNestedClass extends java.lang.Object{
    com.javapapers.java.SyntheticSample$SampleNestedClass(com.javapapers.java.SyntheticSample$SampleNestedClass);
   static java.lang.String access$1(com.javapapers.java.SyntheticSample$SampleNestedClass);
}

access$1 is a java compiler generated getter-method.

This Core Java tutorial was added on 14/04/2013.

Comments on "Java Synthetic Class, Method, Field" Tutorial:

  1. Farrukh says:

    Why java compiler does not generate for protected, public or default access modifier of field a access$X method. What is cause ?. Thanks for article.

  2. Farrukh says:

    import java.lang.reflect.Method;

    public class SyntheticMethod {

    public static void main(String[] args) {

    NestedClass nc = new NestedClass();
    System.out.println(“Nested Variable:” + ” ” + nc.privateVariable);
    int a = nc.a; // getting value by synthetic method: access$2

    Double d = nc.d; // access$?
    char ch = nc.ch; // access$?
    String str = nc.str; // access$?

    Class clazz = nc.getClass();
    Method[] methods = clazz.getDeclaredMethods();
    for (Method method : methods) {
    System.out.println(“Method name: ” + method.getName() + “, isSynthetic: ” + method.isSynthetic());
    }
    }
    private static final class NestedClass {
    private String privateVariable = “A Private Variable”;
    private Integer a = 10;

    protected Double d = 1.1; //?
    Character ch = ‘c’; // ?
    public String str = “str”; //?
    }
    }

  3. Albrecht Gass says:

    I added some code to print the values of the referenced fields for the synthetic methods to show for which fields these synthetic methods are created.
    As it turn out it’s only for the private methods.

    for (Method method : methods) {
    System.out.println(“Method name: “+ method.getName() + “, isSynthetic: “+ method.isSynthetic());
    Class[]cargs = method.getParameterTypes();
    for( Class c: cargs ) {
    System.out.println( ” parameter type: ” + c.getName() );
    }
    System.out.println(” Value: ” + method.invoke(null, new Object[]{ nc }) );
    }

    The output reads like this:
    Nested Variable:A Private Variable
    Method name: access$100, isSynthetic: true
    parameter type: SyntheticMethod$NestedClass
    Value: A Private Variable
    Method name: access$200, isSynthetic: true
    parameter type: SyntheticMethod$NestedClass
    Value: 10

  4. Sumdha says:

    Hi,

    I have added getter method in above code,still synthetic method is created.
    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 );
    System.out.println(” m.isSynthetic: ” + m.isSynthetic());
    }
    }
    private static final class SampleNestedClass {
    private String aPrivateVariable = “A Private Variable!”;

    private String getaPrivateVariable() {
    return aPrivateVariable;
    }

    public void setaPrivateVariable(String aPrivateVariable) {
    this.aPrivateVariable = aPrivateVariable;
    }

    }
    }

    Output:
    Nested Variable:A Private Variable!
    m: private java.lang.String SyntheticSample$SampleNestedClass.getaPrivateVariable()
    m.isSynthetic: false
    m: public void SyntheticSample$SampleNestedClass.setaPrivateVariable(java.lang.String)
    m.isSynthetic: false
    m: static java.lang.String SyntheticSample$SampleNestedClass.access$1(SyntheticSample$SampleNestedClass)
    m.isSynthetic: true

  5. Srikanth says:

    This blog is really helpful with the Java content !! Thanks for sharing !!

  6. Deepak Yadav says:

    An amazing website with lots of java knowledge and always updated with upcoming changes , really nice one……..

  7. Vikas Singh says:

    Ya deepak You are right its a really help ful websites for java lovers…….

  8. srikanth goud says:

    can anyone explain me the code inside of println statement
    System.out.println("Nested Variable: " + nestObj.aPrivateVariable);

  9. srikanth goud says:

    what is this?

    "m: " + m + " m.isSynthetic: " + m.isSynthetic()

    i copy pasted from the author code of s.o.p

  10. srikanth goud says:

    sorry it is printing different i don’t understand the reason but so i am asking in other way what is and(&)quote which is used by the author in s.o.p statement.

Comments are closed for this "Java Synthetic Class, Method, Field" tutorial.