title: Type erasure and code generation in generics
body: <p>I have this sample code/hierarchy to understand how compiler acts in this particular case.</p>
  
  <p>I've the following classes/interfaces;</p>
  
  <p>#1:</p>
  
  <pre><code>abstract class Vehicle&lt;T extends Steering&gt; {
  
     protected T mSteering;
  
     public Vehicle(T mSteering) {
         this.mSteering = mSteering;
     }
  
     void turnLeft() {
         mSteering.toLeft();
     }
  
     void turnRight(){
        mSteering.toRight();
     }
  }
  
  class Car&lt;T extends Steering&gt; extends Vehicle&lt;T&gt; {
  
      Car(T mSteering) {
          super(mSteering);
      }
  
      T getSteering(){
          return mSteering;
      }
  }
  </code></pre>
  
  <p>#2:</p>
  
  <pre><code>interface Steering {
      void toRight();
      void toLeft();
  }
  
  class XSteering implements Steering {
  
      @Override
      public void toRight() {
  
      }
  
      @Override
      public void toLeft() {
          System.out.println("steering left by XSteering");
      }
  }
  
  public class YSteering implements Steering {
  
      @Override
      public void toRight() {
  
      }
  
      @Override
      public void toLeft() {
          System.out.println("steering left by YSteering");
      }
  }
  </code></pre>
  
  <p>#3:</p>
  
  <pre><code>public static void main(String[] args) {
  
      Car c1 = new Car&lt;&gt;(new XSteering());
      c1.turnLeft();
      // XSteering steering1 = c1.getSteering(); // DOES NOT COMPILE
  
      Car c2 = new Car&lt;&gt;(new YSteering());
      c2.turnLeft();
  }
  </code></pre>
  
  <p>The code outputs as expected;</p>
  
  <pre><code>steering left by XSteering
  steering left by YSteering
  </code></pre>
  
  <p>So, when I remove the comments in the following line though;</p>
  
  <pre><code>XSteering steering1 = c1.getSteering();
  </code></pre>
  
  <p>It doesn't compile. </p>
  
  <p>So, when type erasure takes place during compilation, I expect that the return type of the method is replaced with <code>Steering getSteering()</code> as it's the leftmost bound. This is OK. My question is more about what's happening on the call site. Since <code>getSteering()</code> has the generic return type I was also expecting the compiler adds the necessary cast in where you call the function so you wouldn't add an explicit cast to make it work (or in other words, compiler wouldn't give a complication error). Can someone where's my understanding fails in this case? </p>