How covariant method overriding is implemented using bridging Technique in java

后端 未结 3 843
执念已碎
执念已碎 2020-12-18 04:26

While reading on Covariant Overriding, i find out very strange fact,

covariant method overriding is implemented using a bridging technique. it also

3条回答
  •  庸人自扰
    2020-12-18 05:25

    What this means is that if you have a method with a covariant (narrower) return type, the compiler will create a synthetic bridge method for you and invoke the overriding method through this bridge method. Covariance in return type was introduced in Java 5, at the same time as generics and it is implemented using bridge methods.

    Example 1 : Covariance in return type is also implemented using synthetic bridge methods even when there are no generics present.

    For example:

    abstract class A {     
    
       public abstract A get();
    }
    
    class B extends A {
    
      @Override
      public B get() {
         return this;
      }
    }
    

    Will be implemented in bytecode by the compiler using a synthetic bridge method that delegates to the original method. In principle you can imagine that the compiler translates the covariant override to this:

    abstract class A {     
    
       public abstract A get();
    }
    
    class B extends A {
    
      //bytecode only bridge method
      @Override
      public A get() {
         return get;
      } 
    
      public B get() {
         return this;
      }
    }
    

    Example 2 - Generics : Let's look at an example when generics are involved.

    abstract class A {     
    
       public abstract T get();
    }
    
    class B extends A {
    
      @Override
      public String get() {
         return "hello";
      }
    }
    

    The method get() of class B is covariant in return type to the method get in class A. When compiling this bit of code the compiler will perform erasure which means that it will replace generics with their bounds and add casts to make sure that the everything works.

    After erasure the classes look like this:

    abstract class A {
    
       public abstract Object get();
    }
    
    class B extends A {
    
      @Override
      public String get() {
         return "hello";
      }
    }
    

    Now since the method signature of get is public Object get() which is not a signature that is present in class B the compiler will generate a bridge method in class B in order to achieve the overriding.

    You can think of class B looking like the below. However, it is important to note that the below code will never be generated. It would not compile. The compiler just generates the equivalent get method in bytecode.

     class B extends A {
    
      //bridge method
      @Override
      public Object get() {
         return get();
      }
    
      public String get() {
         return "hello";
      }
    }
    

    Every polymorphic use of class B through A that invokes get will invoke the bridge method which will delegate to the real get method.

提交回复
热议问题