Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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?

share|improve this question
1  
? super Shape would work there. "Producer Extends, Consumer Super" – Michael Myers 2 days ago
@MichaelMyers: Au contraire: ideone.com/TYr10C. Base<? super Shape> accepts a Base of any supertype of Shape. – Oli Charlesworth 2 days ago

1 Answer

up vote 19 down vote accepted

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());
share|improve this answer
4  
+1 Or (Math.random() > .5) ? new Base<Square>() : new Base<Circle>(). No way the compiler can figure that one out. – arshajii 2 days ago
Now it's clear. Thanks ! :) – Iza Marek 2 days ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.