I have this sample code/hierarchy to understand how compiler acts in this particular case.
I've the following classes/interfaces;
#1:
abstract class Vehicle<T extends Steering> {
protected T mSteering;
public Vehicle(T mSteering) {
this.mSteering = mSteering;
}
void turnLeft() {
mSteering.toLeft();
}
void turnRight(){
mSteering.toRight();
}
}
class Car<T extends Steering> extends Vehicle<T> {
Car(T mSteering) {
super(mSteering);
}
T getSteering(){
return mSteering;
}
}
#2:
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");
}
}
#3:
public static void main(String[] args) {
Car c1 = new Car<>(new XSteering());
c1.turnLeft();
// XSteering steering1 = c1.getSteering(); // DOES NOT COMPILE
Car c2 = new Car<>(new YSteering());
c2.turnLeft();
}
The code outputs as expected;
steering left by XSteering
steering left by YSteering
So, when I remove the comments in the following line though;
XSteering steering1 = c1.getSteering();
It doesn't compile.
So, when type erasure takes place during compilation, I expect that the return type of the method is replaced with Steering getSteering()
as it's the leftmost bound. This is OK. My question is more about what's happening on the call site. Since getSteering()
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?