9

From this Oracle Java tutorial:

The WildcardError example produces a capture error when compiled:

public class WildcardError {

    void foo(List<?> i) {
        i.set(0, i.get(0));
    }
}

After this error demonstration, they fix the problem by using a helper method:

public class WildcardFixed {
    void foo(List<?> i) {
        fooHelper(i);
    }

    // Helper method created so that the wildcard can be captured
    // through type inference.
    private <T> void fooHelper(List<T> l) {
        l.set(0, l.get(0));
    }
}

First, they say that the list input parameter (i) is seen as an Object:

In this example, the compiler processes the i input parameter as being of type Object.

Why then i.get(0) does not return an Object? if it was already passed in as such?

Furthermore what is the point of using a <?> when then you have to use an helper method using <T>. Would not be better using directly T which can be inferred?

Lii
  • 11,553
  • 8
  • 64
  • 88
Rollerball
  • 12,618
  • 23
  • 92
  • 161
  • This is what Eclipse gives me: `The method set(int, capture#1-of ?) in the type List is not applicable for the arguments (int, capture#2-of ?)` Sounds even more ridiculous. – Marko Topolnik Jun 27 '13 at 10:27
  • I just wrote an [answer](http://stackoverflow.com/questions/30797805/understanding-a-captured-type-in-java/30798066#30798066) which explains wildcard capture for another question. That information seems relevant for this question also. – Lii Jun 12 '15 at 08:38

1 Answers1

4

List<?> does mean list of object of unknown type, it's not the same as List<Object>.

Because we don't know the type of elements in the list result of i.get(0) is considered by Java as Object, and you cannot add Object to List<?>. In case as your Java could be smarter, but in more complex code with <?> wildcards it's easy to make it no type safe.

Mateusz D.
  • 726
  • 5
  • 7