11

I'd like to ask about java type erasure rules.

If we have classes:

public class Shape{}
public class Circle extends Shape{}


public class Base<T extends Shape>{
    T x;
    public void setX(T t){}
}

public class MainClass(){
    public static void main(String... _arg){
         Base<? extends Shape> bs = new Base<Circle>(); 
         bs.setX(new Circle()); // <- compilation problem
    }
}

Can you please explain me why calling setX() method causes compilation problem?

Iza Marek
  • 231
  • 1
  • 5

1 Answers1

21

Because the compiler doesn't know that new Circle is valid. Consider this code:

Base<? extends Shape> bs = new Base<Square>();  // Really a Base<Square> 
bs.setX(new Circle());

(FYI, a very similar example is given in the Java tutorial on wildcards.)

You may now exclaim "But the compiler can see it's really a Base<Square>!". But not in general. Consider this:

Base<? extends Shape> bs = someInterface.getBaseOfSomeKindOfShape();
bs.setX(new Circle());
Oliver Charlesworth
  • 252,669
  • 29
  • 530
  • 650
  • 6
    +1 Or `(Math.random() > .5) ? new Base() : new Base()`. No way the compiler can figure that one out. – arshajii Jul 11 '13 at 15:22