Download presentation
Presentation is loading. Please wait.
1
Generics and Subtyping
What is wrong with the following: List<Integer>[] arrayList1 = new ArrayList<Integer>[10]; ArrayList<Integer>[] arrayList2 = new ArrayList<Integer>[10]; both cause a compile-time "generic array creation" error. Why? my examples are in SubTypingTests.java
2
Superclass Variables A superclass variable can be assigned a subclass object: Number num = new Integer(0); // ok Number is a superclass of Integer
3
Type Constructors Types come in two sorts:
basic types: int, char, Integer, String, etc. type constructors: these are ways to build more complex types from the basic ones e.g. arrays and collections Integer[], ArrayList<String>
4
Covariance A type constructor is covariant if it preserves the super/subclass ordering of its component types. Example using []: Animal is a superclass of Cat Animal[] is a superclass of Cat[]
5
Array Subtyping is Covariant
type S[] is a subtype of T[] when S is a subtype of T e.g. Number[] nums = new Integer[] {1,2,3}; // ok nums[0] = 3.14; // compiles, but raises an // ArrayStoreException at run-time
6
The array element type (Integer) is remembered by Java at run time
called a reified type
7
Invariance A type constructor is invariant if it does not support the super/subclass ordering of its componenet types. Generics are invariant for their parameterized types List< Integer> is a superclass of ArrayList<Integer> ✔ List<Number> is invariant for ArrayList<Integer> ✘ ArrayList<Number> is invariant for ArrayList<Integer> ✘ invariance triggers compile-time errors
8
Superclass vars and Generics
If a collection variable and collection object have the same parameterized type, then superclass variables are still allowed: List<Integer> iList = new ArrayList<Integer>(); // ok List is a superclass of ArrayList compare to the first slide!
9
Subtyping for Generics is Invariant
List<S> is not a subtype of List<T> except where S and T are the same This means that superclass variables are not allowed if S and T are different, even if the collection (List) is the same. e.g. ArrayList<Number> nums = new ArrayList<Integer>(); // causes a compile-time error nums.put(0, 3.14); // Java never gets here
10
Type Erasure Parameterized type information is discarded after compilation has finished. e.g. at run-time, the JRE only knows: List<String> ==> List ArrayList<Fruit> ==> ArrayList Why? For binary compatibility with collections code written before Java 5
11
Problems with Type Erasure
If generic subtype covariance was allowed, then the following code would incorrectly work: ArrayList<Number> nums = new ArrayList<Integer>(); nums.put(0, 3.14); // no run-time error, but there should be!! The reason is that the JRE only knows about ArrayList, not ArrayList<Integer> at run-time.
12
Back to the Question causes a compile time error. Why?
List<Integer>[] arrLists = new ArrayList<Integer>[10]; causes a compile time error. Why? If the code was allowed to compile then type erasure would store ArrayList[] as the type of the object.
13
Then the following could happen:
List<Double> doubleList = new ArrayList<Double>(); doubleList.add(Double.valueOf(1.23)); arrLists[0] = doubleList; // no error occurs, but should!! The last assignment would work because both objects (doubleList and arrLists[0]) are of type ArrayList at run-time.
14
Wildcards add covariant subtyping to generics
List<S> is a subtype of List<? extends T> when S is a subtype of T e.g. List<Integer> ints = Arrays.asList(1,2,3); List<? extends Number> numsExt = ints; numsExt.put(2, 3.14); // compile-time error, not run-time // as happens with arrays
15
Contravariant Subtyping for Generics
List<S> is a subtype of List<? super T> when S is a supertype of T Arrays do not support contravariant subtyping
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.