Compiler warnings when declaring generic types

Why does the compiler give a warning when declaring a variable as

List<? extends Object> list = new LinkedList(); 

Attention:

 Note: ZiggyTest.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 

But it does not give a warning when I declare a variable as

 List<?> list = new LinkedList(); 
+4
source share
2 answers

I cannot explain why the compiler will not consider them as equivalent, but given that this is not so, I will try to explain why it refuses to do this.

The first ( List<? extends Object> ) states that the type of objects stored in the List has an unknown type obtained from Object . The second ( List<?> ) Says less; he just says that the type of objects in the list is unknown. He does not mention the expected supertype as the upper bound of an unknown type.

To test the first assumption, the compiler wants to hear that you are saying something about the expected types stored in the List instance, constructed here as a raw LinkedList type that says nothing about it. However, if you were to create an instance of type LinkedList<Object> , you at least guarantee that covariant readings against the instance will be consistent with your statement: namely, that the things on this list are a kind of Object .

Now all this seems silly, because every reference / non-primitive type in Java extends Object , so there should be no difference in interpretation between List<? extends Object> List<? extends Object> and List<?> ; in the end, the second implies the first, by virtue of a language-type system that provides for a single-level hierarchy of classes.

+1
source

This appears in Java 5 and later if you use collections without type specifiers (e.g. Arraylist() instead of ArrayList<String>() ). This means that the compiler cannot verify that you are using the collection in a safe way using generics .

To get rid of the warning, simply indicate what type of objects you store in the collection. So instead

 List list = new ArrayList(); 

should be like

 List<String> list = new ArrayList<String>(); 

In your case, if you change this statement as follows,

 List<? extends Object> list = new LinkedList<Object>(); 

it will be compiled without warning, because now we make it safe with the generic type ( <Object> ).

+2
source

Source: https://habr.com/ru/post/1388845/


All Articles