About Briged Methods

I was reading the book Java Generics and Collections by Maurice Naftalin and Phillip Wadler and I learned something very interesting that I want to share with you.

Now, the introduction of generics created a problem to the concept of method signature when it came to interacting with legacy code. Let's see an example with the implementation of the Comparable interface prior to Java 1.5. The Integer class would look somewhat like this:

  1. public interface {
  2. public int compareTo( o);
  3. }
  4.  
  5. public final class implements {
  6. private final int value;
  7.  
  8. public (int value){
  9. this.value = value;
  10. }
  11.  
  12. public int compareTo( o){
  13. this.compareTo(() o);
  14. }
  15.  
  16. public int compareTo( i){
  17. return (value > i.value) ? -1 : (value == i.value) ? 0 : 1;
  18. }
  19. }

If you would like to verify this for yourselves go take a look at the JDK 1.4 API Documentation for the class java.lang.Integer you will see both methods declared as I did in the snippet above.

As you can see the implementation of the method required by the Comparable interface is actually a bridge to get to the actual method that carries out the work.

Interestingly, the introduction of generics in JDK 1.5 brought a solution to this problem, but the solution was not compatible with legacy code. In JDK 1.5 the implementation of Integer would look somewhat like this:

  1. public interface Comparable<T> {
  2. public int compareTo(T o);
  3. }
  4.  
  5. public final class implements Comparable<Integer> {
  6. private final int value;
  7.  
  8. public (int value){
  9. this.value = value;
  10. }
  11.  
  12. public int compareTo( i){
  13. return (value > i.value) ? -1 : (value == i.value) ? 0 : 1;
  14. }
  15. }

Unfortunately, now the method compareTo(Integer i) can only accept Integer objects as parameters, whereas the legacy method of JDK 1.4 could accepted any Object. This would make JDK 1.5 incapable of compiling legacy code if it weren't because now the compiler adds the bridged method automatically for us.

In fact, if you review the for the Integer class you will notice that the bridge method is not declared anymore. If you review the source code for Integer class you will notice the method is not declared there either.

However, if you do some reflection and print all the methods in the class, you will notice the bridge method is present in the compiled version of the class.

  1. for( m : .class.getMethods()){
  2. if(m.getName().equals("compareTo"))
  3. .out.println(m.toGenericString());
  4. }

This prints the following to the main output:

  1. public int java.lang..compareTo(java.lang.)
  2. public int java.lang..compareTo(java.lang.)

This means that the bridge method has been automatically created by the compiler to make the current generified implementation compatible with legacy code.