Problems � Often you need the same behavior for different kind of classes � Use Object references to accommodate any object type Java Generics Java Generics � Use Generic classes and Method � The use of Object references induces cumbersome code Version 1.0 Oct 2006 2 Example Example � We may need to represent ID of persons in � You can use it with different types different forms Person a = new Person(“Al”,”A”,new Integer(123)); public class Person { String first;String last; Object ID; Person b = new Person(“Pat”,”B”,”s32”); � You may need casts.. Person(String f, String l, Object ID){ this.first = f; this.last = l; Integer id = (Integer) a.getID(); � ..that may be dangerous this.ID = ID; } } Integer id = (Integer) b.getID(); ClassCastException at run-time 3 4
Generic class Generics use � Declaration is longer but... public class Person<T> { String first; Person<Integer> a = new Person<Integer> String last; ("Al","A",new Integer(123)); T ID; Person<String> b = new Person<String> Person(String first,String last,T ID){ ("Pat","B","s32"); this.first = first; � ..use is more compact and safer this.last = last; this.ID = ID; Integer id1 = a.getID(); } Integer id2 = b.getID(); String ids = b.getID(); T getID(){ return ID; } } Compiler error: type mismatch 5 6 Generic type declaration Generic collections � Syntax: � All collection interfaces and classes have been redefined as Generics ( class | interface ) Name <P 1 { ,P 2 } > � Use of generics lead to code that is � Parameters: � safer � uppercase letter � more compact � usually: T(ype), E(lement), K(ey), V(alue) � easier to understand � equally performing 7 8
Generic list - excerpt Example � Using a list of Integers public interface List<E>{ void add(E x); � W/o generics ( ArrayList list ) Iterator<E> iterator(); list.add(0, new Integer(42)); int n= ((Integer)(list.get(0))).intValue(); } � With generics ( ArrayList<Integer> list ) public interface Iterator<E>{ E next(); list.add(0, new Integer(42)); int n= ((Integer)(list.get(0))).intValue(); boolean hasNext(); � + autoboxing ( ArrayList<Integer> list ) } list.add(0,new Integer(42)); int total = list.get(0).intValue(); 9 10 Example Example � A class representing a point with different � Computing distance from origin: precisions public double distance(){ public class Point<T> { return Math.sqrt( T x; x.doubleValue()*x.toDouble() T y; + y.doubleValue()*y.toDouble()); method undefined public Point(T x, T y){ } for type T this.x = x; � We need to bind T: this.y = y; } public class Point<T extends Number> {..} } 11 12
Bounded types Generics subtyping � Allow to express constraints when defining � We must be careful about inheritance when generic types generic types are involved � String is a subtype of Object class C<T extends B1 { & B2 } > � List<String> is not not s-t of List<Object> � class C can be instantiated only with types derived from B1 (and B2 etc.) List<String> ls = new ArrayList<String>(); List<Object> lo = ls; if this were legal then... lo.add(new Object()); String s = ls.get(0); .. we could end up assigning an Object to a String reference 13 14 Wildcard - example Bounded wildcard - example � An attempt to have a generic method: � We need a generic sum function List<Integer> list=new LinkedList<Integer>(); void printAll(Collection<Object> c) { sum(list); for (Object e: c) � double sum(List<Number> list) System.out.println(e); � not applicable to List<Integer> } � won't work with e.g. Collection<String> � double sum(List<T extends Number> list) � We ought to use a wildcard: � not a valid syntax, not defining a new type � double sum(List<? extends Number> list) void printAll(Collection<?> c) { .. } � we need to use a bounded wildcard pronounced: Collection of unknown 15 16
Wildcards Lower bound - example � A sorted collection should contain elements � Allow to express (lack of) constraints when that can be ordered using generic types � An element E can be order if it directly � G<?> implements Comparable<E> � G of unknown, unbounded interface SortedCollection � G<? extends B> <E extends Comparable<E>> � upper bound: only sub-types of B � but also if any of its super-classes implements the relative Comparable � G<? super D> � lower bound: only super-types of D interface SortedCollection <E extends Comparable<? super E>> 17 18 Generic method declaration Generic methods � Sytax: � A generic method can be declared both in a common or generic class modifiers <T> ret_ type name(pars) � pars can be: <T> T method(T t) <N extends Number> N method(List<N> t) � as usual <N extends Number> void method(List<N> t) � T void method(List<? extends Number> t) � type<T> � wilcards are more compact when a type parameter is used only once 19 20
Generics classes Type erasure � Classes corresponding to generic types are � There is only one class generated (by the generated by type erasure compiler) for each generic type declaration � The erasure of a generic class is a raw type – where any reference to the parameters is substituted with the parameter erasure Person<Integer> a = new Person<Integer> ("Al","A",new Integer(123)); � Erasure of a parameter is the erasure of its first constraint Person<String> b = new Person<String> ("Pat","B","s32"); – If no constraint then erasure is Object boolean same=(a.getClass()==b.getClass()); � The erasure of a non-generic type is the type itself believe it or not same is true 21 22 Type erasure - examples Type erasure – consequences I � In: <T> � Compiler makes control only when a generic type is used, not within it. � T ==> Object � In: <T extends Number> � Whenever a generic or a parameter is used a cast is added to its erasure � T ==> Number � In: <T extends Number & Comparable> � instanceOf and .class cannot be used on generic types � T ==> Number � valid for G<?> equivalent to the raw type 23 24
Type erasure – consequences II Type erasure– consequences III � It is not possible to instantiate an object of � Overload and ovverride must be considered the generic's parameter type after type erasure class Base<T> { class G<T> { T[] toArray(){ void m(int x){} Object The compiler T[] res = new T[n]; void m(T t){} cannot instantiate T t = new T(); these objects void m(String s){} Number }} <N extends Number> void m(N x){} � It is not possible to substitute the erasure in an void m(List<?> l){} instantiation statement } 25 26 Generics and inheritance � Inherintance together with generic types leads to several possibilities � It is not possible to implement two generic interfaces instantiated with different types class Value implements Comparable<Value> class Extended Value extends Value implements Comparable<ExtValue> 27
Recommend
More recommend