Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generics - Bridge method?

Tags:

java

generics

Something called the "bridge method" concept related to Java Generics made me stop at a point and think over it.

Btw, I only know that it occurs at the bytecode level and is not available for us to use.

But I am eager to know the concept behind the "bridge method" used by the Java compiler.

What exactly happens behind the scenes and why it is used?

Any help with an example would be greatly appreciated.

like image 379
Saurabh Gokhale Avatar asked Feb 15 '11 17:02

Saurabh Gokhale


People also ask

What is Java bridge method?

Bridge Method: These are methods that create an intermediate layer between the source and the target functions. It is usually used as part of the type erasure process. It means that the bridge method is required as a type safe interface.

What are the two 2 types of Erasure?

3. Types of Type Erasure. Type erasure can occur at class (or variable) and method levels.

Why are Java generics implements using erasure?

Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to: Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded.

Is Java generics compile time or runtime?

Generics are checked at compile-time for type-correctness. The generic type information is then removed in a process called type erasure. For example, List<Integer> will be converted to the non-generic type List , which ordinarily contains arbitrary objects.

What is a generic method in Java?

Generic Method: Generic Java method takes a parameter and returns some value after performing a task. It is exactly like a normal function, however, a generic method has type parameters that are cited by actual type.

What does bridge method do in Java?

What bridge method does is silently override the method in parent class with all the information from a method with the same name but a different signature. With the help of the bridge method, polymorphism worked. Though on the surface, you override the parent class method with a method of different signature.

What is the difference between generic types and functions in Java?

There are some fundamental differences between the two approaches to generic types. Generic Method: Generic Java method takes a parameter and returns some value after performing a task. It is exactly like a normal function, however, a generic method has type parameters that are cited by actual type.

How to create objects of generic class in Java?

To create objects of generic class, we use following syntax. // To create an instance of generic class BaseType <Type> obj = new BaseType <Type> () Note: In Parameter type we can not use primitives like 'int','char' or 'double'. We can also pass multiple Type parameters in Generic classes.


2 Answers

It's a method that allows a class extending a generic class or implementing a generic interface (with a concrete type parameter) to still be used as a raw type.

Imagine this:

public class MyComparator implements Comparator<Integer> {    public int compare(Integer a, Integer b) {       //    } } 

This can't be used in its raw form, passing two Objects to compare, because the types are compiled in to the compare method (contrary to what would happen were it a generic type parameter T, where the type would be erased). So instead, behind the scenes, the compiler adds a "bridge method", which looks something like this (were it Java source):

public class MyComparator implements Comparator<Integer> {    public int compare(Integer a, Integer b) {       //    }     //THIS is a "bridge method"    public int compare(Object a, Object b) {       return compare((Integer)a, (Integer)b);    } } 

The compiler protects access to the bridge method, enforcing that explicit calls directly to it result in a compile time error. Now the class can be used in its raw form as well:

Object a = 5; Object b = 6;  Comparator rawComp = new MyComparator(); int comp = rawComp.compare(a, b); 

Why else is it needed?

In addition to adding support for explicit use of raw types (which is mainly for backwards compatability) bridge methods are also required to support type erasure. With type erasure, a method like this:

public <T> T max(List<T> list, Comparator<T> comp) {    T biggestSoFar = list.get(0);    for ( T t : list ) {        if (comp.compare(t, biggestSoFar) > 0) {           biggestSoFar = t;        }    }    return biggestSoFar; } 

is actually compiled into bytecode compatible with this:

public Object max(List list, Comparator comp) {    Object biggestSoFar = list.get(0);    for ( Object  t : list ) {        if (comp.compare(t, biggestSoFar) > 0) {  //IMPORTANT           biggestSoFar = t;        }    }    return biggestSoFar; } 

If the bridge method didn't exist and you passed a List<Integer> and a MyComparator to this function, the call at the line tagged IMPORTANT would fail since MyComparator would have no method called compare that takes two Objects...only one that takes two Integers.

The FAQ below is a good read.

See Also:

  • The Generics FAQ - What is a bridge method?
  • Java bridge methods explained (thanks @Bozho)
like image 165
Mark Peters Avatar answered Oct 04 '22 16:10

Mark Peters


If you want to understand why you need bridge method, you better understand what happens without it. Suppose there is no bridge method.

class A<T>{   private T value;   public void set(T newVal){     value=newVal   } }  class B extends A<String>{   public void set(String newVal){     System.out.println(newVal);     super.set(newVal);   } } 

Notice that after erasure, method set in A became public void set(Object newVal) since there is no bound on Type parameter T. There is no method in class B the signature of which is the same as set in A. So there is no override. Hence, when something like this happened:

A a=new B(); a.set("Hello World!"); 

Polymorphism won't work here. Remember you need to override the method of parent class in child class so that you can use parent class var to trigger polymorphism.

What bridge method does is silently override the method in parent class with all the information from a method with the same name but a different signature. With the help of the bridge method, polymorphism worked. Though on the surface, you override the parent class method with a method of different signature.

like image 42
ch48h2o Avatar answered Oct 04 '22 17:10

ch48h2o