Java Generics - PowerPoint PPT Presentation

slide1 n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Java Generics PowerPoint Presentation
Download Presentation
Java Generics

play fullscreen
1 / 51
Java Generics
388 Views
Download Presentation
akina
Download Presentation

Java Generics

- - - - - - - - - - - - - - - - - - - - - - - - - - - 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 2

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

  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 4

  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? 5

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

  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) 7

  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(); 8

  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(); 9

  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> 10

  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. 11

  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(); 12

  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(); 13

  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? 14

  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; } // … } 15

  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) 16

  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); } } ); 17

  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 lurk here? 18

  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); 19

  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); 20

  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 21

  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 22

  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 new MathBox<Double>(32.1); //Legal new MathBox<String>(“No good!”);//Illegal 23

  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. 24

  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> { … } 25

  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: 26

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

  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()); } } 28

  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! 29

  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); } } 30

  31. Correct way – Use Wildcards • We cannot add arbitrary objects to a collection of wild card type. Collection<?> c = new ArrayList<String>(); c.add(new Object()); // this will give a compile time error Since we don’t know what type that is, we cannot pass in anything. The only type we can pass for the above example is String. 31

  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; 32

  33. Assertions

  34. 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” ;

  35. 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.

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

  37. Enabling Assertions Assertion cannot be used to check the arguments for public methods.The following code is not right: 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");}

  38. Questions & Answers: 38

  39. 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>(); 39

  40. 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>()); 40

  41. 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. 41

  42. 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)” 42

  43. 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>. 43

  44. 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. 44

  45. 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> { 45

  46. 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 */ } } 46

  47. 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 47

  48. Mock Exam Questions: What is the result? A. passed stuff B. stuff passed C. passed An AssertionError is thrown with the word “stuff” added to the stack trace. D. passed An AssertionError is thrown without the word “stuff” added to the stack trace. E. passed An AssertionException is thrown with the word “stuff” added to the stack trace. F. passed An AssertionException is thrown without the word “stuff” added to the stack trace. Question 65 Given: 12. public class AssertStuff { 13. 14. public static void main(String [] args) { 15. int x= 5; 16. int y= 7; 17. 18. assert (x> y): “stuff”; 19. System.out.println(”passed”); 20. } 21. } And these command line invocations: java AssertStuff java -ea AssertStuff 48

  49. Mock Exam Questions: Question 66 Click the Exhibit button. 1. public class Test { 2. 3. public static void main(String [] args) { 4. boolean assert = true; 5. if(assert) { 6. System.out.println(”assert is true”); 7. } 8. } 9. 10. } Given: javac -source 1.3 Test.java What is the result? A. Compilation fails. B. Compilation succeeds with errors. C. Compilation succeeds with warnings. D. Compilation succeeds without warnings or errors. 49

  50. Mock Exam Questions: Question 67 Given: 23.int z=5; 24. 25. public void stuff1(int x) { 26. assert (x> 0); 27. switch(x) { 28. case 2: x= 3; 29. default: assert false; } } 30. 31. private void stuff2(int y) { assert (y < 0); } 32. 33. private void stuff3() { assert (stuff4()); } 34. 35. private boolean stuff4() { z = 6; return false; } Which is true? A. All of the assert statements are used appropriately. B. Only the assert statement on line 31 is used appropriately. C. The assert statements on lines 29 and 31 are used appropriately. D. The assert statements on lines 26 and 29 are used appropriately. E. The assert statements on lines 29 and 33 are used appropriately. F. The assert statements on lines 29, 31, and 33 are used appropriately. G. The assert statements on lines 26, 29, and 31 are used appropriately. 50