11

Consider the following code:

import java.util.ArrayList; import java.util.List; public class UnboundedWildcardProblem { public static void main(String[] args) { List<?> a = new ArrayList(); List<? extends Object> b = new ArrayList(); } } 

The creation of List<?> doesn't produce any warnings, but the creation of List<? extends Object> produces an unchecked warning:

Warning: java: unchecked conversion required: java.util.List<? extends java.lang.Object> found: java.util.ArrayList 

I searched for possible reasons and found some discussions:

List<?> vs List<? extends Object>

What's the difference between <?> and <? extends Object> in Java Generics?

But after reading these discussions it seems to me that List<?> and List<? extends Object> are the same thing.

So, what is the reason for such compiler behaviour?

EDIT:

The single flag used for compilation was an Xlint:unchecked flag.

12
  • I mean... aren't those different generic declarations? List<?> seems different from List<? extends Object> Commented Nov 18, 2015 at 22:02
  • 3
    Don't use raw types. This has very little to do with the declared type of a and b. Commented Nov 18, 2015 at 22:03
  • 2
    "The creation of List<?> doesn't produce any warnings". Wrong, it does, because "ArrayList is a raw type." Commented Nov 18, 2015 at 22:05
  • 1
    The first snippet DOES produce a warning, contrary to what the OP says. Commented Nov 18, 2015 at 22:09
  • 2
    Recompile with "-Xlint:rawtypes": stackoverflow.com/questions/697879/… Commented Nov 18, 2015 at 22:22

1 Answer 1

11

The creation of List<?> doesn't produce any warnings, but the creation of List<? extends Object> produces an unchecked warning

In fact, if you compile your code with the -Xlint:all or just Xlint option, you would get a warning for the List<?> a = new ArrayList(); statement, something like:

 warning: [rawtypes] found raw type: ArrayList List<?> a = new ArrayList(); ^ missing type arguments for generic class ArrayList<E> where E is a type-variable: E extends Object declared in class ArrayList 

However, the reason why you're not getting an unchecked warning per se is because the type List<?> contains only unbounded wildcards as mentioned in this section from the Java Language Specification:

There is an unchecked conversion from the raw class or interface type (§4.8) G to any parameterized type of the form G<T1,...,Tn>.

...

Use of an unchecked conversion causes a compile-time unchecked warning unless all type arguments Ti (1 ≤ i ≤ n) are unbounded wildcards (§4.5.1), or the unchecked warning is suppressed by the SuppressWarnings annotation (§9.6.4.5).

However in this section, it is mentioned:

The wildcard ? extends Object is equivalent to the unbounded wildcard ?.

which shows a subtle inconsistency in the compiler.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the detailed explanation!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.