1 / 54

Java Generics

Java Generics. Jiafan Zhou. Concepts. Generalizing Collection Classes Using Generics with other Java 1.5 Features Integration of Generics with Previous Releases User built generic classes. What Are Generics?. Generics abstract over Types

helga
Download Presentation

Java Generics

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Java Generics Jiafan Zhou

  2. Concepts • Generalizing Collection Classes • Using Generics with other Java 1.5 Features • Integration of Generics with Previous Releases • User built generic classes

  3. What Are Generics? • Generics abstract over Types • Classes, Interfaces and Methods can be Parameterized by Types • Generics provide increased readability and type safety

  4. Java Generic Programming • Java has class Object • Supertype of all object types • This allows “subtype polymorphism” • Can apply operation on class T to any subclass S (S extends T) • Java 1.0 – 1.4 do not have templates • No parametric polymorphism • Many consider this the biggest deficiency of Java • Java type system does not let you cheat • Can cast from supertype to subtype • Cast is checked at run time

  5. Example generic construct: Stack • Stacks possible for any type of object • For any typet, can have type stack_of_t • Operationspush, popwork for any type • In C++, would write generic stack class template <type t> class Stack { private: t data; Stack<t> * next; public: void push (t* x) { … } t* pop ( ) { … } }; //(still happens at runtime) • What can we do in Java?

  6. Simple Example Using Interfaces interface List<E> { void add(E x); Iterator<E> iterator(); } interface Iterator<E> { E next(); boolean hasNext(); }

  7. What Generics Are Not • Generics are not templates • Unlike C++, generic declarations are • Typechecked at compile time • Generics are compiled once and for all • Generic source code not exposed to user The type checking with Java 1.5 Generics changes the way one programs (as the next few slides show)

  8. Java 1.0 vs. Generics class Stack { void push(Object o) { ... } Object pop() { ... } ...} String s = "Hello"; Stack st = new Stack(); ... st.push(s); ... s = (String) st.pop(); class Stack<A> { void push(A a) { ... } A pop() { ... } ...} String s = "Hello"; Stack<String> st = new Stack<String>(); st.push(s); ... s = st.pop();

  9. How to Use Generics List<Integer> xs =new LinkedList<Integer>(); xs.add(new Integer(0)); Integer x = xs.iterator.next(); Compare with List xs = new LinkedList(); xs.add(new Integer(0)); Integer x = (Integer)xs.iterator.next();

  10. Collection Class Example HashMap<Intger, Double> hm = new HashMap<Intger, Double> (); // Note Auto-boxing from 1.5. hm.put (1,2.0); double coeff = hm.get(1); Hashmap1.4 hm => Hashmap1.5<Object, Object>

  11. Collection Class Example It is possible to restrict a collection type to contain objects of a particular type only. Such types are called generic types. For example:List<Double> myList = new LinkedList<Double>(); The compiler guarantees that only Double wrapper objects added to this list.

  12. List Usage: Without Generics List ys = new LinkedList(); ys.add("zero"); List yss; yss = new LinkedList(); yss.add(ys); String y = (String) ((List)yss.iterator().next()).iterator().next(); // Evilrun-time error Integer z = (Integer)ys.iterator().next();

  13. List Usage: With Generics List<String> ys = new LinkedList<String>(); ys.add("zero"); List<List<String>> yss; yss = new LinkedList<List<String>>(); yss.add(ys); String y = yss.iterator().next().iterator().next(); // Compile-time error – much better! Integer z = ys.iterator().next();

  14. List Implementation w/o Generics class LinkedList implements List { protected class Node { Object elt; Node next; Node(Object elt){elt = e; next = null;} } protected Node h, t; public LinkedList() {h = new Node(null); t = h;} public void add(Object elt){ t.next = new Node(elt); t = t.next; } } Inner Class Remember these?

  15. List Implementation With Generics class LinkedList<E >implements List<E> protected class Node { E elt; Node next; Node(E elt){elt = e; next = null;} } protected Node h, t; public LinkedList() {h = new Node(null); t = h;} public void add(E elt){ t.next = new Node(elt); t = t.next; } // … }

  16. Recall the Iterator Interface class LinkedList<E >implements List<E> • // … public Iterator<E> iterator(){ return new Iterator<E>(){ protected Node p = h.next; public boolean hasNext(){return p != null;} public E next(){ E e = p.elt; p = p.next; return e; } } } } Anonymous Inner Class (see Swing scribble example)

  17. Methods Can Be Generic Also interface Function<A,B>{ B value(A arg);} interface Ntuple<T> { <S> Ntuple<S> map(Function<T,S> f); } Ntuple<Integer> nti = ....; nti.map (new Function<Integer, Integer> { Integer value(Integer i) { return new Integer(i.intValue()*2); } } );

  18. Example: Generics and Inheritance 1st consider this code w/o Generics class ListUtilities { public static Comparable max(List xs) { Iterator xi = xs.iterator(); Comparable w = (Comparable) xi.next(); while (xi.hasNext()) { Comparable x = (Comparable) xi.next(); if (w.compareTo(x) < 0) w = x; } return w; } } What dangers here?

  19. Consider what happens List xs = new LinkedList(); xs.add(new Byte(0)); Byte x = (Byte) ListUtilities.max(xs); List ys = new LinkedList(); ys.add(new Boolean(false)); // Evilrun-time error Boolean y = (Boolean) ListUtilities.max(ys);

  20. With Generics We Get Compile Check List<Byte> xs = new LinkedList<Byte>(); xs.add(new Byte(0)); Byte x = ListUtilities.max(xs); List<Boolean> ys = new LinkedList<Boolean>(); ys.add(new Boolean(false)); // Compile-time error Boolean y = ListUtilities.max(ys);

  21. Generics and Inheritance • Suppose you want to restrict the type parameter to express some restriction on the type parameter • This can be done with a notion of subtypes • Subtypes (weakly construed) can be expressed in Java using inheritance • So it’s a natural combination to combine inheritance with generics • A few examples follow

  22. Priority Queue Example interface Comparable<I> { boolean lessThan(I); } class PriorityQueue<T extends Comparable<T>> { T queue[ ] ; … void insert(T t) { ... if ( t.lessThan(queue[i]) ) ... } T remove() { ... } ... } Said to be bounded

  23. Bounded Parameterized Types • The <E extends Number> syntax means that the type parameter of MathBox must be a subclass of the Number class • We say that the type parameter is bounded newMathBox<Integer>(5); //Legal because Integer is a subclass of Number new MathBox<Double>(32.1); //Legal because Double is a subclass of Number new MathBox<String>(“No good!”);//Illegal because String is not a subclass of Number

  24. Bounded Parameterized Types • Inside a parameterized class, the type parameter serves as a valid type. So the following is valid. public class OuterClass<T> { private class InnerClass<E extends T> { … } … } Syntax note:The <A extends B> syntax is valid even if B is an interface.

  25. Bounded Parameterized Types • Java allows multiple inheritance in the form of implementing multiple interfaces, so multiple bounds may be necessary to specify a type parameter. The following syntax is used then: <T extends A & B & C & …> • Example interface A {…} interface B {…} class MultiBounds<T extends A & B> { … }

  26. Generics and Subtyping • Is the following code snippet legal? List<String> ls = new ArrayList<String>(); //1 List<Object> lo = ls; //2 • Line 1 is certainly legal. What about line 2? Is a List of Strings a List of Object. Intuitive answer for most is “sure!”. But wait! • The following code (if line 2 were allowed) would attempt to assign an Object to a String! lo.add(new Object()); // 3 String s = ls.get(0); // 4:

  27. Generics and Subtyping • In generics, if Child is a subtype of Parent, and T is some generic type declaration, it is not the case that T<Child> is subtype of T<Parent> • For example, the second line of code here will not pass the compiling List<String> ls = new ArrayList<String>(); List<Object> lo = ls; // compiling fails

  28. Wildcards • Consider the problem of writing code that prints out all the elements in a collection before 1.5. void printCollection(Collection c) { Iterator i = c.iterator(); for (k = 0; k < c.size(); k++) { System.out.println(i.next()); } }

  29. 1st Naive Try w/ Generics void printCollection(Collection<Object> c) { for (Object e : c) { System.out.println(e); } } • The problem is that this new version is much less useful than the old one. • The old code could be called with any kind of collection as a parameter, • The new code only takes Collection<Object>, which, as is not a supertype of all kinds of collections! • In other words, passing Collection<String> or Collection<Integer> will be invalid.

  30. Correct way – Use Wildcards • So what is the supertype of all kinds of collections? • Pronounced “collection of unknown” and denoted Collection<?>, • A collection whose element type matches anything. • It’s called a wildcard type for obvious reasons. void printCollection(Collection<?> c) { for (Object e : c) { System.out.println(e); } }

  31. Correct way – Use Wildcards • We cannot add objects to a collection of wild card type. Collection<?> c = new ArrayList<String>(); c.add(new Object()); // this will give a compile time error c.add(new String(“I am a string”)); // this will give a compile time error Since we don’t know what type that is, we cannot pass in anything, even String object.

  32. Correct way – Use Wildcards • We can declare variables which can accept collections of any subclass of a particular class, say X, by using the bounded wild card type. • <? extends X> e.g. List<? extends Mammal> list; • Alternatively, we can also declare variables which can accept collections of any superclass of a particular class. • <? super X> e.g. List<? super Mammal> list; When using extends/super, both the baseclass is allowed. (i.e. in the above example, Mammal is allowed)

  33. Diamond Expression • In Java 7 or later, diamond expression helps to simplify the generics declaration. • The diamond notation is not possible in Java6. • List<Integer> arrayList = new ArrayList<>(); • So a little bit simpler.

  34. Assertions

  35. Assertions Overview Assertions let you test your assumptions during development. private void methodA(int num) { assert (num>=0); // throws an AssertionError useNum(num + x); // if this test isn't true } Assertions can have either one or two expressions The first expression must always result in a boolean value. The second expression can be anything that results a message. E.g. assert(num>=0) : “num is not bigger than zero” ;

  36. Assertions Assertion is a conditional expression that should evaluate to true if and only if the code is working correctly. If the expression evalidates to false, an error is signaled. Assertions can be turned off completely. AssertionError is thrown to indicate that an assertion has failed.

  37. Enabling Assertions You can use “assert” as an identifier prior to java 4. In java 4 and onwards, if you want use assert as a keyword, you have to enable assertion-awareness during compile time. javac -source 1.3 MyJava.java In java 6 and 7, “assert” is a keyword by default To enable assertion: java -ea MyJava Or java –enableassertion MyJava

  38. Enabling Assertions Many people do not use Assertions and really hate when others do use them. Assertions in Java have a lot of limitations. Assertion cannot be used to check the arguments for public methods.The following code still compiles but is not appropriate: public void method1(Object value) { assert value == null;} In such a case, use the exception.public void method1(Object value) { if (value == null) throw new RuntimeException("Arguments null");} Method invocation cannot be used inside the assert. e.g. assert (method1())

  39. Homework

  40. Homework • Update your banking system using generics design. • Update the project where you use collections with generics. • Use some assertions for your unit test code.

  41. Questions & Answers

  42. Mock Exam Questions: Question 175: Given: 1. import java.util.*; 2. public class Test { 3. public static void main(String[] args) { 4. List<String> strings = new ArrayList<String>(); 5. // insert code here 6. } 7. } Which four, inserted at line 5, will allow compilation to succeed? (Choose four.) A. String s = strings.get(0); B. Iterator i1 = strings.iterator(); C. String[] array1 = strings.toArray(); D. Iterator<String> i2 = strings.iterator(); E. String[] array2 = strings.toArray(new String[1]); F. Iterator<String> i3 = strings.iterator<String>(); 42

  43. Mock Exam Questions: Question 176 Given: 1. import java.util.*; 2. public class Old { 3. public static Object get()(List list) { 4. return list.get(0); 5. } 6. } Which three will compile successfully? (Choose three.) A. Object o = Old.get0(new LinkedList()); B. Object o = Old.get0(new LinkedList<?>()); C. String s = Old.getfl(new LinkedList<String>()); D. Object o = Old.get0(new LinkedList<Object>()); E. String s = (String)Old.get0(new LinkedList<String>()); 43

  44. Mock Exam Questions: Question 177 Given: 11. public static void append(List list) { list.add(”0042”); } 12. public static void main(String[] args) { 13. List<Integer> intList = new ArrayList<Integer>(); 14. append(intList); 15. System.out.println(intList.get(0)); 16. } ‘What is the result? A. 42 B. 0042 C. An exception is thrown at runtime. D. Compilation fails because of an error in line 13. E. Compilation fails because of an error in line 14. 44

  45. Mock Exam Questions: Question 178 Given a pre-generics implementation of a method: 11. public static int sum(List list) { 12. int sum = 0; 13. for ( Iterator iter = list.iterator(); iter.hasNext(); ) { 14. int i = ((Integer)iter.next()).intValue(); 15. sum += i; 16. } 17. return sum; 18. } Which three changes must be made to the method sum to use generics? (Choose three.) A. remove line 14 B. replace line 14 with “int i = iter.next();” C. replace line 13 with “for (int i : intList) {“ D. replace line 13 with “for (Iterator iter : intList) {“ E. replace the method declaration with “sum(List<int> intList)” F. replace the method declaration with “sum(List<Integer> intList)” 45

  46. Mock Exam Questions: Question 179 Given: classA {} class B extends A {} class C extends A {} class D extends B {} Which three statements are true? (Choose three.) A. The type List<A> is assignable to List. B. The type List<B> is assignable to List<A>. C. The type List<Object> is assignable to List<?>. D. The type List<D> is assignable to List<? extends B>. E. The type List<? extends A> is assignable to List<A>. F. The type List<Object> is assignable to any List reference. G. The type List<? extends B> is assignable to List<? extends A>. 46

  47. Mock Exam Questions: Question 180 Given: 11. public void addStrings(List list) { 12. list.add(”foo”); 13. list.add(”bar”); 14. } What must you change in this method to compile without warnings? A. add this code after line 11: list = (List<String>) list; B. change lines 12 and 13 to: list.add<String>(”foo”); list.add<String>(”bar”); C. change the method signature on line 11 to: public void addStrings(List<? extends String> list) { D. change the method signature on line 11 to: public void addStrings(List<? super String> list) { E. No changes are necessary. This method compiles without warnings. 47

  48. Mock Exam Questions: Question 182 Given: 11. // insert code here 12. private N min, max; 13. public N getMin() { return min; } 14. public N getMax() { return max; } 15. public void add(N added) { 16. if (min == null || added.doubleValue() <min.doubleValue()) 17. min = added; 18. if (max == null ||added.doubleValue() > max.doubleValue()) 19. max = added; 20. } 21. } Which two, inserted at line 11, will allow the code to compile? (Choose two.) A. public class MinMax<?> { B. public class MinMax<? extends Number> { C. public class MinMax<N extends Object> { D. public class MinMax<N extends Number> { E. public class MinMax<? extends Object> { F. public class MinMax<N extends Integer> { 48

  49. Mock Exam Questions: Question 183 A programmer must create a generic class MinMax and the type parameter of MinMax must implement Comparable. Which implementation of MinMax will compile? A. class MinMax<E extends Comparable<E>> { E min=null; E max=null; public MinMax() { } public void put(E value) { /* store min or max */ } } B. class MinMax<E implements Comparable<E>> { E min=null; E max=null; public MinMax() { } public void put(E value) { /* store min or max */ } } C. class MinMax<E extends Comparable<E>> { <E> E min = null; <E> E max = null; public MinMax() { } public <E> void put(E value) { /* store min or max */ } } D. class MinMax<E implements Comparable<E>> { <E> E min = null; <E> E max = null; public MinMax() { } public <E> void put(E value) { /* store min or max */ } } 49

  50. Mock Exam Questions: Quetion 64 Given: 8. public class test { 9. public static void main(String [] a) { 10. assert a.length == 1; 11. } 12. } Which two will produce an AssertionError? (Choose two.) A. java test B. java -ea test C. java test file1 D. java -ea test file1 E. java -ea test file1 file2 F. java -ea:test test file1 50

More Related