Synthetic methods are often referred to as bridge methods in Java generics world. These methods are created by the Java compiler as a result of type erasure when the signature of the inherited methods change when a type extends or implements parameterized classes or interfaces. The compiler generates synthetic methods in subtypes of parameterized supertypes to make sure that subtyping works as expected.

For instance, let us try to extend the Lock interface defined in concurrency package and define an extended lock method which takes a type parameter. We use the hidden “-XD-printflat” compiler option to generate the java files after type erasure.

javac -d tmp -XD-printflat LockExImpl.java

LockEx interface

public interface LockEx extends java.util.concurrent.locks.Lock {
  //extended lock method
  void lockEx(T t);
}

LockExImpl Before Erasure

final class LockExImpl<T> extends java.util.concurrent.locks.ReentrantLock
			implements LockEx<LockExImpl>  {
  public void lockEx(LockExImpl mutex) {
    throw new UnsupportedOperationException("Not supported yet.");
  }
}

LockExImpl After Erasure

final class LockExImpl extends java.util.concurrent.locks.ReentrantLock
                                     implements LockEx {
  LockExImpl() {
    super();
  }

  public void lockEx(LockExImpl mutex) {
    throw new UnsupportedOperationException("Not supported yet.");
  }

  /*synthetic*/

  public void lockEx(Object x0) {
    this.lockEx((LockExImpl)x0);
  }
}