Card 08/ 09
All 9 cards
ExerciseDifficulty: Advanced1 min
Six Lines: Which Ones Does the Compiler Refuse
Six lines. Decide which compile and which do not, and why. All six before the reveal.
List<String> strings = new ArrayList<>();
// 1
List<Object> objects = strings;
// 2
List<?> anything = strings;
// 3
anything.add("more");
// 4
Object first = anything.get(0);
// 5
List<? extends Number> numbers = new ArrayList<Integer>();
// 6
numbers.add(1);Which of the six compile?
| Compiles? | Why | |
|---|---|---|
| 1 | No | A list of a subtype is not a list of the supertype — adding anything would break it |
| 2 | Yes | A wildcard accepts a list of anything |
| 3 | No | Nothing is known about the element type, so nothing is safe to add |
| 4 | Yes | Every element is at least an Object, so reading one is safe |
| 5 | Yes | Integer is a subtype of Number, which is what extends accepts |
| 6 | No | extends means the list might be of some other subtype, so adding is refused |
Lines three and four together are the whole of what a wildcard means. You may take things out as Object and you may not put anything in, because the compiler knows the list has some element type and not which one.
Line six is the one people argue with. numbers might be pointing at a List<Double>, and adding an Integer to it would be exactly the corruption generics exist to prevent.