Java Generics http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf Lecture 17 -- CS1122 Summer 2008
Java Generics quick review When you see <... > in Java, you are dealing with generics Generics allow you to abstract over types Do not think about hierarchy in terms of the formal type parameters (stuff in < >) Each generic type is unique
Last time we talked about... Defining simple generics. Formal type parameters come between?
Last time we talked about... Defining simple generics. Formal type parameters come between? <... >
Last time we talked about... Defining simple generics. Formal type parameters come between? <... > Formal type parameters are usually named with?
Last time we talked about... Defining simple generics. Formal type parameters come between? <... > Formal type parameters are usually named with? single capital letters
Last time we talked about... Defining simple generics. Formal type parameters come between? <... > Formal type parameters are usually named with? single capital letters Generics and subtyping. Is List<SomeClass> a subtype of List<Object>?
Last time we talked about... Defining simple generics. Formal type parameters come between? <... > Formal type parameters are usually named with? single capital letters Generics and subtyping. Is List<SomeClass> a subtype of List<Object>? no
Last time we talked about... Defining simple generics. Formal type parameters come between? <... > Formal type parameters are usually named with? single capital letters Generics and subtyping. Is List<SomeClass> a subtype of List<Object>? no Wildcards What character is used in wild cards?
Last time we talked about... Defining simple generics. Formal type parameters come between? <... > Formal type parameters are usually named with? single capital letters Generics and subtyping. Is List<SomeClass> a subtype of List<Object>? no Wildcards What character is used in wild cards? the question mark. ex: List<?>
Last time we talked about... Defining simple generics. Formal type parameters come between? <... > Formal type parameters are usually named with? single capital letters Generics and subtyping. Is List<SomeClass> a subtype of List<Object>? no Wildcards What character is used in wild cards? the question mark. ex: List<?> What is different about a bounded wildcard?
Last time we talked about... Defining simple generics. Formal type parameters come between? <... > Formal type parameters are usually named with? single capital letters Generics and subtyping. Is List<SomeClass> a subtype of List<Object>? no Wildcards What character is used in wild cards? the question mark. ex: List<?> What is different about a bounded wildcard? List<? extends Shape>
Generic Methods static void fromarraytocollection(object[] a, Collection<?> c){ for (Object o : a) { c.add(o); // compile time error
Generic Methods static void fromarraytocollection(object[] a, Collection<?> c){ for (Object o : a) { c.add(o); // compile time error Can t add an Object to a Collection of?
Generic Methods static <T> void fromarraytocollection(t[] a, Collection<T> c){ for (T o : a) { c.add(o); Now we have a type named T We can add objects of type T to a Collection declared with type T
Sample Code Object[] oa = new Object[100]; Collection<Object> co = new ArrayList<Object>(); //T inferred to be fromarraytocollection(oa, co);
Sample Code Object[] oa = new Object[100]; Collection<Object> co = new ArrayList<Object>(); //T inferred to be Object fromarraytocollection(oa, co);
Sample Code Object[] oa = new Object[100]; Collection<Object> co = new ArrayList<Object>(); //T inferred to be Object fromarraytocollection(oa, co); String[] sa = new String[100]; Collection<String> cs = new ArrayList<String>(); // T inferred to be fromarraytocollection(sa, cs); // T inferred to be fromarraytocollection(sa, co);
Sample Code Object[] oa = new Object[100]; Collection<Object> co = new ArrayList<Object>(); //T inferred to be Object fromarraytocollection(oa, co); String[] sa = new String[100]; Collection<String> cs = new ArrayList<String>(); // T inferred to be String fromarraytocollection(sa, cs); // T inferred to be Object fromarraytocollection(sa, co);
Sample Code Object[] oa = new Object[100]; Collection<Object> co = new ArrayList<Object>(); Integer[] ia = new Integer[100]; Float[] fa = new Float[100]; Number[] na = new Number[100]; Collection<Number> cn = new ArrayList<Number>(); //T inferred to be fromarraytocollection(ia, cn); // T inferred to be fromarraytocollection(fa, cn);
Sample Code Object[] oa = new Object[100]; Collection<Object> co = new ArrayList<Object>(); Integer[] ia = new Integer[100]; Float[] fa = new Float[100]; Number[] na = new Number[100]; Collection<Number> cn = new ArrayList<Number>(); //T inferred to be Number fromarraytocollection(ia, cn); // T inferred to be Number fromarraytocollection(fa, cn);
Sample Code Object[] oa = new Object[100]; Collection<Object> co = new ArrayList<Object>(); Integer[] ia = new Integer[100]; Float[] fa = new Float[100]; Number[] na = new Number[100]; Collection<Number> cn = new ArrayList<Number>(); // T inferred to be fromarraytocollection(na, cn); // T inferred to be fromarraytocollection(na, co);
Sample Code Object[] oa = new Object[100]; Collection<Object> co = new ArrayList<Object>(); Integer[] ia = new Integer[100]; Float[] fa = new Float[100]; Number[] na = new Number[100]; Collection<Number> cn = new ArrayList<Number>(); // T inferred to be Number fromarraytocollection(na, cn); // T inferred to be Object fromarraytocollection(na, co);
Sample Code Collection<String> cs = new ArrayList<String>(); Number[] na = new Number[100]; // does this work? -- NO fromarraytocollection(na, cs); There is no relation between String and Number, so no type can be resolved for T and a compiler error results.
Generic Methods vs. Wildcards Consider the following... interface Collection<E> { public boolean containsall(collection<?> c); public boolean addall(collection<? extends E> c); Compare to: interface Collection<E> { public <T> boolean containsall(collection<t> c); //type variables can have bounds too! public <T extends E> boolean addall(collection<t> c);
Generic Methods vs. Wildcards interface Collection<E> { public <T> boolean containsall(collection<t> c); //type variables can have bounds too! public <T extends E> boolean addall(collection<t> c); In both methods, T is used only once. Return type doesn t depend on T. Infer... T is being used for polymorphism. Allows us to pass a variety of types to the parameter. This is a better place for wildcards.
Generic Methods allow us to express dependencies among types of among parameters and/or return type of method if this dependency doesn t exist, use wildcards
Generic Methods AND Wildcards class Collections { public static <T> void copy(list<t> dest, List<? extends T> src){ //code omitted Why have we used a generic method?
Generic Methods AND Wildcards class Collections { public static <T> void copy(list<t> dest, List<? extends T> src){ //code omitted Why have we used a generic method? the parameters depend on each other
Generic Methods AND Wildcards class Collections { public static <T> void copy(list<t> dest, List<? extends T> src){ //code omitted Compare to... class Collections { public static <T, S extends T> void copy (List<T> dest, List<S> src){ //code omitted
Generic Methods AND Wildcards class Collections { public static <T, S extends T> void copy (List<T> dest, List<S> src){ //code omitted Type S is only used once. Only the type of src is related to S. Replace S with a wildcard. Makes code clearer and more concise.
Generic Methods AND Wildcards static List<List<? extends Shape>> history = new ArrayList<List<? extends Shape>>(); public void drawall(list<? extends Shape> shapes) { history.addlast(shapes); for (Shape s: shapes) { s.draw(this);
Summary Use generic methods when the types of multiple parameters are related. Use generic methods when the return type of the method is related to the types of one or more parameters. You can use generic methods and wildcards together. Use wildcards to make code clearer and more concise.