Effective Java: 3rd Edition Generics

Slides:



Advertisements
Similar presentations
Java Review Interface, Casting, Generics, Iterator.
Advertisements

Generic programming in Java
Java Generics.
Java Generics. 2 The Dark Ages: Before Java 5 Java relied only on inclusion polymorphism  A polymorphism code = Using a common superclass Every class.
Generics OOP Tirgul What is it good for ? Stack myStack = new Stack() ; // old version (1.4.2) myStack.push(new Integer(0)) ; int x = ((Integer)
1 Generics and Using a Collection Generics / Parameterized Classes Using a Collection Customizing a Collection using Inheritance Inner Classes Use of Exceptions.
1 Chapter 21 Generics. 2 Objectives F To know the benefits of generics (§21.1). F To use generic classes and interfaces (§21.2). F To declare generic.
Generic Subroutines and Exceptions CS351 – Programming Paradigms.
Generic Java 21/ What is generics? To be able to assign type variables to a class These variables are not bound to any specific type until the.
©The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Chapter Chapter 17 Animated Version Generics and Type Safety.
ADSA: Subtypes/ Advanced Data Structures and Algorithms Objective –explain how subtyping/subclassing and generics are combined in Java –introduce.
Generics In Java 1.5 By Manjunath Beeraladinni. Generics ➲ New feature in JDK1.5. ➲ Generic allow to abstract over types. ➲ Generics make the code clearer.
Chapter 21 Generics 1. Generics - Overview Generic Methods specify a set of related methods Generic classes specify a set of related types Software reuse.
Effective Java: Generics Last Updated: Spring 2009.
Generics1 Parametrized classes and methods. Generics2 What are generics Generics are classes or interfaces that can be instantiated with a variety of.
Generics1 Parametrized classes and methods. Generics2 What are generics Generics are classes or interfaces that can be instantiated with a variety of.
Generics1 Parametrized classes and methods. Generics2 What are generics Generics are classes or interfaces that can be instantiated with a variety of.
1 Generics and Using a Collection Generics / Parameterized Classes Using a Collection Customizing a Collection using Inheritance Inner Classes Use of Exceptions.
ArrayList, Multidimensional Arrays
Generics CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L.
Java 5 Part 1 CSE301 University of Sunderland Harry Erwin, PhD.
Generics CompSci 230 S Software Construction.
CMSC 330: Organization of Programming Languages Java Generics.
1 CSE 331 Generics (Parametric Polymorphism) slides created by Marty Stepp based on materials by M. Ernst, S. Reges, D. Notkin, R. Mercer, Wikipedia
Liang, Introduction to Java Programming, Tenth Edition, (c) 2013 Pearson Education, Inc. All rights reserved. 1 Chapter 19 Generics.
Parametric Polymorphism and Java Generics. Announcements One day extension on HW5 Because of an error in my HW5 config HW6 out, due November 10 Grades.
CSE 331 SOFTWARE DESIGN & IMPLEMENTATION GENERICS/PARAMETRIC POLYMORPHISM Autumn 2011 We We Abstraction.
©SoftMoore ConsultingSlide 1 Generics “Generics constitute the most significant change in the Java programming language since the 1.0 release.” – Cay Horstmann.
GENERICS AND THE JAVA COLLECTIONS FRAMEWORK Lecture 16 CS2110 – Fall 2015 Photo credit: Andrew Kennedy.
Generic(Parameterized ) types Mehdi Einali Advanced Programming in Java 1.
1 CSC 2053 New from AutoBoxing 3 Before J2SE 5.0, working with primitive types required the repetitive work of converting between the primitive.
Java How to Program, 9/e © Copyright by Pearson Education, Inc. All Rights Reserved.
Effective Java, Chapter 9: Exceptions Items Last modified Fall 2012 Paul Ammann.
1 Chapter 21 Generics. 2 Objectives F To use generic classes and interfaces (§21.2). F To declare generic classes and interfaces (§21.3). F To understand.
(C) 2010 Pearson Education, Inc. All rights reserved. Java How to Program, 8/e.
James Wilcox / Winter 2016 CSE 331 Software Design and Implementation Lecture 14 Generics 2.
JAVA GENERICS Lecture 16 CS2110 – Spring 2016 Photo credit: Andrew Kennedy.
ADT’s, Collections/Generics and Iterators
CIS265/506 Cleveland State University – Prof. Victor Matos
More on Java Generics Multiple Generic Types Bounded Generic Types
Introducing Java Generics and Collections
More Generics רובי בוים ומתי שמרת
Generic(Parameterized ) Types
Chapter 20 Generic Classes and Methods
Java Generics Lecture 14 CS2110 – Fall 2016
Generics and Subtyping
Generics, Lambdas, Reflections
Generics.
Java Generics.
Parametric Polymorphism and Java Generics
Advanced Programming Behnam Hatami Fall 2017.
Chapter 19 Generics Dr. Clincy - Lecture.
Generics (Parametric Polymorphism)
Advanced Programming in Java
CSE 331 Software Design and Implementation
CSE 331 Software Design and Implementation
Generics.
Generic programming in Java
Chapter 19 Generics.
Chapter 21 Generics.
Effective Java, 3rd Edition Chapter 10: Exceptions
Type Safety, Generics, Lambdas, Class Object
Generics, Lambdas, Reflections
Chapter 19 Generics Jung Soo (Sue) Lim Cal State LA.
Effective Java, Chapter 9: Exceptions
Chapter 21 Generics.
Chapter 19 Generics.
CSE 143 Lecture 21 Advanced List Implementation
COMP204 Bernhard Pfahringer (with input from Robi Malik)
Chapter 19 Generics.
Presentation transcript:

Effective Java: 3rd Edition Generics Last Updated: Fall 2018

Agenda Material From Joshua Bloch Cover Items 26-31, 33 Bottom Line: Effective Java: Programming Language Guide Cover Items 26-31, 33 “Generics” Chapter Bottom Line: Generics are safer, than raw types But generics are also more complex Raw types are allowed for backwards compatibility

Item 26: Don’t Use Raw Types in New Code A class (interface) with one or more type parameters is a generic class (interface) Examples: List is a raw type List<E> is a generic interface List<String> is a parameterized type String is the actual type parameter corresponding to E

Example: Replacing raw types // Now a raw collection type – don’t do this private final Collection stamps = …; // Contains only Stamps // Erroneous insertion of coin into stamp collection stamps.add(new Coin(…)); // Oops! We’re set up for ClassCastException later // Parameterized collection type - typesafe private final Collection<Stamp> stamps = …; stamps.add(new Coin(…)); // result is instead a compile time error, which is good // Now a raw iterator type – don’t do this! for (Iterator I = stamps.iterator(); i.hasNext(); ) { Stamp s = (Stamp) i.next(); // Throws ClassCastException …// Do something with the stamp } // for-each loop over parameterized collection – typesafe for (Stamp s: stamps) { // No (explicit) cast …// Do something with the stamp

Example: Mixing generic and raw types // Uses raw type (List) – fails at runtime public static void main(String[] args) { List<String> strings = new ArrayList<String>(); unsafeAdd(strings, new Integer(42)); String s = strings.get(0); //Exception from compiler generated cast } // note use of raw types private static void unsafeAdd(List list, Object o) { list.add(o); // There is a compile time warning: Test.java:10: warning: unchecked call to add(E) in raw type List ^ // If we ignore the warning, and run the program, we get a ClassCastException // where the compiler inserted the cast // If we try the following, it won’t compile (see Item 25) private static void unsafeAdd( List<Object> list, Object o) { list.add(o);}

Example: Using Wildcards // Use of raw type for unknown element type – don’t do this! static int numElementsInCommonSet (Set s1, Set s2) { int result = 0; for (Object o1: s1) { if (s2.contains(o1)) result ++; } return result; } // Unbounded wildcard type – typesafe and flexible static int numElementsInCommonSet (Set<?> s1, Set<?> s2) { // We’ll revisit this type of example in Item 27

Example: Using Wildcards // Do the question marks really buy you anything? // Answer: Wildcard is typesafe, // because you can’t add *anything* (except null) to Collection<?> // Two exceptions: Raw types ok in Class Literals: List.class, not List<String>.class instanceof operator if (o instanceof Set) { // raw type ok Set<?> m = (Set<?>) o; // Wildcard type // Why the exceptions? Compatibility with old Java

Terminology Term Example Item Parameterized type List<String> Item 23 Actual type parameter String Item 23 Generic type List<E> Items 23, 26 Formal type parameter E Item 23 Unbounded wildcard type List<?> Item 23 Raw type List Item 23 Bounded type parameter <E extends Number> Item 26 Recursive type bound <T extends Comparable<T>> Item 27 Bounded wildcard type List<? extends Number> Item 28 Generic method static <E> List<E> asList(E[] a) Item 27 Type token String.class Item 29

Item 27: Eliminate Unchecked Warnings Generics result in many compiler warnings Eliminate them As a last resort, suppress the warnings Do so as at local a level as possible Options are class down to local declaration Use the @SuppressWarnings annotation Some are easy: Set<Lark> exaltation = new HashSet(); // warning Set<Lark> exaltation = new HashSet <Lark>(); // no warning

Example: Suppressing Warnings public <T> T[] toArray (T[] a) { if (a.length < size) return (T[]) Arrays.copyOf(elements, size, a.getClass()); System.arraycopy(elements, 0, a, 0, size); if (a.length > size) a[size] = null; return a; } The compiler generates a warning: ArrayList.java:305: warning [unchecked] unchecked cast found : Object[], required T[] Suppressing the warning: if (a.length < size) { // This cast is correct because the array we’re creating // is of the same type as the one passed in, which is T[] @SuppressWarnings(“unchecked”) T[] result = (T[]) Arrays.copyOf(elements, size, a.getClass()); return result; }

Item 28: Prefer Lists to Arrays Lists play well with generics Generic array creation not typesafe (hence illegal) No new List<E>[], new List<String>[] , or new E[] Arrays are covariant; generics are invariant If Sub is a subtype of Super Then Sub[] is a subtype of Super[] But List<Sub> is not a subtype of List<Super> Arrays are reified; generics are erased Generics are compile time only

Example: Covariance vs. Invariance // Fails at runtime Object[] objectArray = new Long[1]; objectArray[0] = “I don’t fit in!”; // Throws ArrayStoreException // Won’t compile List<Object> o1 = new ArrayList<Long>(); o1.add(“I don’t fit in!”); // Incompatible types Not compiling is better than a runtime exception. This is basically an argument for why invariance is preferable to covariance for generics. Later, we’ll see how to relax this.

Example: Illustrating type (non) safety // Why generic array creation is illegal – won’t compile 1) List<String>[] stringLists = new List<String>[1]; // won’t compile 2) List<Integer> intList = Arrays.asList(42); 3) Object[] objects = stringLists; 4) objects[0] = intList; 5) String s = stringLists[0].get(0); // compiler generated cast to String Suppose 1) compiled (it won’t) 2) Creates and initializes a List<Integer> with one element 3) Stores the List<String> object into an Object array variable, note, this is legal because arrays are covariant 4) Stores the List<Integer> into the sole element of the Object array this succeeds because generics are implemented by erasure. The runtime type is simply List[], so there is no exception 5) Now, we’ve stored a List<Integer> instance into an array that is declared to hold only List<String> instances. So, we get a ClassCastException

Example: Reduction Function // Reduction without generics, and with concurrency flaw! static Object reduce(List list, Function f, Object initVal) { synchronized (list) { Object result = initVal; for (Object o: list) result = f.apply(result, o); // alien method call return result; } interface Function { Object apply (Object arg1, Object arg2); Flaw: Calls alien method from synchronized region Flaw: Doesn’t use generics

Example Continued // Reduction without generics or concurrency flaw static Object reduce(List list, Function f, Object initVal) { Object[] snapshot = list.toArray(); // Locks list internally Object result = initVal; for (Object o: snapshot) result = f.apply(result, o); return result; } Flaw: Still doesn’t use generics

Example Continued // Naïve generic version of reduction – won’t compile static <E> E reduce(List <E> list, Function <E> f, E initVal) { // E[] snapshot = list.toArray(); // Won’t compile E[] snapshot = (E[]) list.toArray(); // Still generates a warning E result = initVal; for (E e: snapshot) result = f.apply(result, e); return result; } // Generic interface interface Function<T> { T apply (T arg1, T arg2); Flaw: Won’t compile without cast Flaw: Cast still results in warning (that needs to be suppressed) Flaw: Possible (with minor variations) to get ClassCastException at runtime

Example: Using Lists instead of Arrays // List-based generic reduction static <E> E reduce(List <E> list, Function <E> f, E initVal) { List <E> snapshot; synchronized (list) { snapshot = new ArrayList<E>(list); } E result = initVal; for (E e: snapshot) result = f.apply(result, e); return result; Bonus: No possibility of ClassCastException at runtime

Item 29: Favor Generic Types Parameterize collection declarations Use the generic types Implementer has to work harder But clients have type safety Stack example: How to support this? public static void main (String[] args) { Stack<String> stack = new Stack<String>(); for (String arg: args) { stack.push(arg);} while (!stack.isEmpty()) { …stack.pop()…} }

Example: Converting collection to generics public class Stack { // Original Version – no generics private Object [] elements; private int size = 0; private static final int CAP = 16; public Stack() { elements = new Object [CAP];} public void push( Object e ) { ensureCapacity(); elements [size++] = e; } public Object pop() { if (size == 0) { throw new ISE(…); } Object result = elements [--size]; elements[size] = null; return result; // remainder of Stack omitted – See Bloch

Example: Converting collection to generics public class Stack <E> { // First cut at generics – won’t work private E [] elements; // Alternate 2: Leave as Object private int size = 0; private static final int CAP = 16; public Stack() { elements = new E [CAP];} // error; generic array creation // Alternate 1: = new (E[]) Object [CAP];} // warning // @SuppressWarning(“unchecked”) //public Stack() { elements = new (E[]) Object [CAP];} // warning suppressed public void push( E e ) { ensureCapacity(); elements [size++] = e; } public E pop() { if (size == 0) { throw new ISE(…); } E result = elements [--size]; // Error for Alternate 2; also cast and suppress warning elements[size] = null; return result;

Item 30: Favor Generic Methods Just as classes benefit from generics So do methods Writing generic methods is similar to writing generic types

Example: Generic method // Uses raw types – unacceptable! (Item 23) public static Set union (Set s1, Set s2) { Set result = new HashSet(s1); // Generates a warning result.addAll(s2); // Generates a warning return result; } // Generic method public static <E> Set <E> union (Set <E> s1, Set <E> s2) { Set <E> result = new HashSet <E> (s1); result.addAll(s2); // The first <E> is the type parameter list // Example from the java.util.Collection // The generics can get a bit redundant… Map <String, List<String>> anagrams = new HashMap<String, List<String>>();

Example: Recursive Type Bound // Returns the maximum value in a list – uses recursive type bound public static <T extends Comparable<T>> T max (List <T> list) { Iterator <T> i = list.iterator(); T result = i.next(); while (i.hasNext()) { T t = i.next(); // Note: no need for a cast if (t.compareTo(result) > 0) result = t; } return result; Questions What happens if the list is empty? What about null values in list? What does a contract look like for this method? Note the type parameter: <T extends Comparable<T>> Note the return type: T

Item 31: Use bounded wildcards to increase API Flexibility public class Stack <E> { // First cut at generics – won’t work public Stack() public void push( E e ) public E pop() public boolean isEmpty() } // pushAll method without a wildcard type – deficient! public void pushAll( Iterable<E> src) { for (E e : src) { push(e); } // wildcard type for parameter that serves as an E producer public void pushAll( Iterable<? extends E> src) { // wildcard type for parameter that serves as an E consumer public void popAll ( Collection<? super E> dst) { while (!isEmpty()) { dst.add(pop()); }

The PECS mnemonic // PECS – producer extends, consumer super // Recall earlier example public static <E> Set <E> union (Set <E> s1, Set <E> s2) // Are parameters consumers or producers? ( Producers, so, extend) public static <E> Set <E> union (Set <? extends E> s1, Set <? extends E> s2) // Note that return type should still be Set<E>, not Set <? extends E> // otherwise, clients will have to use wildcards… Set<Integer> integers = … Set<Double> doublse = … Set<Number> numbers = union ( integers, doubles); // compiler error Set<Number> numbers = union.<Number> ( integers, doubles); // type parameter works // max example public static <T extends Comparable<T>> T max (List <T> list ) // original public static <T extends Comparable<? super T>> T max (List<? extends T> list) // PECS

Item 33: Consider typesafe heterogeneous Containers // Typesafe heterogeneous container pattern – implementation public class Favorites private Map<Class<?>, Object> favorites = new HashMap(<Class<?>, Object>(); public <T> void putFavorite(Class<T> type, T instance) { if (type == null) { throw new NPE… } favorites.put (type, instance); } public <T> T getFavorite(Class<T> type) { return type.cast(favorites.get(type)); // Fairly subtle stuff…