Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generics wildcard extends final class

Tags:

java

generics

Why does Java doesn't throw any warning when compiling my TestGenerics class, considering that the String class is final and cannot be extended?

import java.util.*;
    public class TestGenerics { 
        public void addStrings(List<? extends String> list) {
          // some code here
        }
    }
}
like image 901
L4zy Avatar asked Jul 31 '13 12:07

L4zy


2 Answers

Let's say I had a method like this:

public List<? extends T> filterOutNulls(List<T> input) { ...

Granted, not the best signature in the world, but still perfectly legal. What would happen if I passed a List<String> to that method? According to the signature, it returns a List<? extends String>. If Java disallowed that type, it'd be impossible to use this method for List<String> (or at least, it'd be impossible to use the return value).

Secondarily, the extends syntax is still useful in this case, since List<String> and List<? extends String> have different restrictions -- specifically, you can't add anything but a null literal to List<? extends String>. I'll sometimes use ? extends to signify that a collection is read-only (since the only Ts you can pass in are null), and ? super to signify write-only (since you can only get out Ts as Object). This isn't completely fool-proof (you can still call remove methods, pass in nulls, downcast, etc) but serves as a gentle reminder of how the collection is probably meant to be used.

like image 99
yshavit Avatar answered Oct 05 '22 05:10

yshavit


The compiler doesn't really take note of that fact, because it doesn't matter. Strings are still allowed in the list, and in the final product, the possibility of anything extending String is not found. After erasure, it comes out like this:

public void addStrings(List list)

As you can see, there is now no suggestions of a class extending String. If you do create a class extending String, that will be itself a compile error. There's no need for javac to worry about that.

like image 23
tbodt Avatar answered Oct 05 '22 05:10

tbodt