Presentation is loading. Please wait.

Presentation is loading. Please wait.

©SoftMoore ConsultingSlide 1 Generics “Generics constitute the most significant change in the Java programming language since the 1.0 release.” – Cay Horstmann.

Similar presentations


Presentation on theme: "©SoftMoore ConsultingSlide 1 Generics “Generics constitute the most significant change in the Java programming language since the 1.0 release.” – Cay Horstmann."— Presentation transcript:

1 ©SoftMoore ConsultingSlide 1 Generics “Generics constitute the most significant change in the Java programming language since the 1.0 release.” – Cay Horstmann

2 ©SoftMoore ConsultingSlide 2 Generics Added to Java in version 5 Similar to C++ templates and Ada generics Support typed collection classes and typed methods Reduce the need for casting Provide additional compile-time checking for code correctness Characteristics –easy to use –not easy to implement

3 ©SoftMoore ConsultingSlide 3 Generics Example Before Java 5 and generics List customers = new LinkedList();... Customer c = (Customer) customers.get(0); Using generics List customers = new LinkedList ();... Customer c = customers.get(0); // no cast necessary

4 ©SoftMoore ConsultingSlide 4 Generics Allow a type or method to operate on objects of various types while providing compile-time type safety. Add compile-time type safety to the Collections Framework Eliminate the drudgery of casting. One of the most requested new features of Java 5

5 ©SoftMoore ConsultingSlide 5 A Simple Generic Class public class Pair { private T first; private S second; public Pair(T first, S second) { this.first = first; this.second = second; } public T getFirst() { return first; } public S getSecond() { return second; } }

6 ©SoftMoore ConsultingSlide 6 Using Class Pair Creating an instance of the generic class Pair namedAcct = new Pair ("John", acct); Since Java 7, the second set of type arguments can be omitted from the constructor as long as the compiler can determine or infer the type arguments from the context. Pair namedAcct = new Pair<>("John", acct); This pair of angle brackets, <>, is informally called the diamond.

7 Using Class Pair (continued) The generic class Pair can be used –as the type of a method parameter –as the return type of a method Note that both generic parameters can have the same type, as in Pair. ©SoftMoore ConsultingSlide 7

8 ©SoftMoore ConsultingSlide 8 Example: Defining a Generic Class Excerpt from the definitions of the class List and Iterator in package java.util public interface List { void add(E x); Iterator iterator(); } public interface Iterator { E next(); boolean hasNext(); } formal type parameter

9 ©SoftMoore ConsultingSlide 9 Type Variables A generic class or interface is declared with a type variable (often simply E) enclosed in angle brackets. The type variable denotes an element type that can be used within the generic class. A generic class can be instantiated with any class or interface type List accounts = new ArrayList (); List comps = new ArrayList (); A generic class cannot be instantiated with a primitive type such as int or double (use wrapper classes).

10 ©SoftMoore ConsultingSlide 10 Naming Type Variables Type Variable Name Meaning EElement type in a collection KKey type in a map VValue type in a map T, S, UGeneral types

11 ©SoftMoore ConsultingSlide 11 Advantages of Generics More readable code More correct code –can’t add a String to a list instantiated to hold bank accounts –checking performed by the compiler rather than at run time. But the price we pay is language complexity.

12 ©SoftMoore ConsultingSlide 12 Erasure Intuitively, List behaves like a version of List where E has been uniformly replaced by String. This intuition can be helpful, but it’s also misleading. Generics are implemented by the Java compiler as a front-end conversion called erasure. Erasure gets rid of (or erases) all generic type information, resulting in raw type, a list of Object. The checks for correctness and consistency are performed only by the compiler.

13 ©SoftMoore ConsultingSlide 13 Example: Pair Class After Erasure public class Pair { private Object first; private Object second; public Pair(Object first, Object second) { this.first = first; this.second = second; } public Object getFirst() { return first; } public Object getSecond() { return second; } }

14 Interface Iterable package java.lang; import java.util.Iterator; public interface Iterable { Iterator iterator(); } ©SoftMoore ConsultingSlide 14 Implementing this interface allows an object to be the target of a “forEach” loop.

15 ©SoftMoore ConsultingSlide 15 Enhanced “for” Loop Defined in Java 5 (a.k.a. Java 1.5) Syntax for (Classname variable : collection) statement; // may be a compound statement Works for collections and arrays –Collection must implement the Iterable interface Reduces the need for working with iterators and index variables.

16 ©SoftMoore ConsultingSlide 16 Example: Enhanced “for” Loop Assume we have a list of Customer objects List customers = new ArrayList (); Without the enhanced “for” loop (before Java 5) Iterator iter = customers.iterator(); while (iter.hasNext()) { Customer c = (Customer) iter.next(); System.out.println(c); } Using the enhanced “for” loop for (Customer c : customers) System.out.println(c);

17 ©SoftMoore ConsultingSlide 17 Example: Using Enhanced “for” Loop with Primitive Types and Arrays int sum(int[] a) { int result = 0; for (int i : a) result += i; return result; }

18 ©SoftMoore ConsultingSlide 18 Autoboxing Java makes a distinction between primitive types ( int, double, char, etc.) and classes. Problem: Can’t put primitive types into collections. Possible solutions prior to Java 5 –use wrapper classes ( Integer, Double, Character, etc.) –write your own List class to handle primitive types (separate class for each type) With autoboxing, the compiler performs automatic conversions between primitive types and their corresponding wrapper classes.

19 ©SoftMoore ConsultingSlide 19 Example: Autoboxing Without autoboxing (before Java 5) List list = new LinkedList(); list.add(new Integer(13));... int n = ((Integer)(list.get(0))).intValue(); With autoboxing List list = new LinkedList (); list.add(13);... int n = list.get(0);

20 ©SoftMoore ConsultingSlide 20 Using Autoboxing The wrapper classes are still used. The compiler automatically converts between primitive classes and wrapper classes. Acceptable performance for occasional use Not appropriate for performance-critical applications and scientific numerical computing

21 ©SoftMoore ConsultingSlide 21 Constraining Type Variables Type variables can be constrained with bounds public static > E min(E[] a) {... } “extends” actually means “extends” or “implements”. Bounds can be either classes or interfaces Can be called with String[] since String implements Comparable You can specify more than one type bound & Cloneable>

22 ©SoftMoore ConsultingSlide 22 Generics and Subtyping Consider the following code: public class BankAccount { … } public class SavingsAccount extends BankAccount { … } List a1 = new ArrayList (); List a2 = new ArrayList (); We can add an object of class SavingsAccount to the list, but List is not a subclass of List.

23 ©SoftMoore ConsultingSlide 23 Wildcards It is possible to declare a collection whose element type matches anything. void printCollection(Collection c) { for (Object e : c) { System.out.println(e); } Collection is a “collection of unknown”

24 ©SoftMoore ConsultingSlide 24 Using Wildcards Given a List, we can call get() and make use of the result. The result type is an unknown type, but we always know that it is an object. It is therefore safe to assign the result of get() to a variable of type Object or pass it as a parameter where the type Object is expected.

25 ©SoftMoore ConsultingSlide 25 Bounded Wildcards: Motivation Assume we have an abstract class Shape and several subclasses of Shape ( Circle, Rectangle, etc.). Method drawAll() will draw all shapes in a list. public void drawAll(List shapes) { for (Shape s: shapes) s.draw(); } However, drawAll() will not accept List as a valid type parameter.

26 ©SoftMoore ConsultingSlide 26 Bounded Wildcards We can rewrite method drawAll() using a bounded wildcard so that it will accept List as a type parameter. public void drawAll(List shapes) { for (Shape s: shapes) s.draw(); }

27 ©SoftMoore ConsultingSlide 27 Generic Methods: Motivation Suppose you want to create a method that takes an array of objects and a collection and puts all objects in the array into the collection. static void copy (Object[] source, Collection destination) { for (Object o : source) destination.add(o); // compile time error } Problem: You cannot add objects into a collection of unknown type.

28 ©SoftMoore ConsultingSlide 28 Generic Method Method with a type variable static void print(List l)... Can be defined inside ordinary or a generic classes Can be static or non-static Compiler infers the actual type when the method is called – not explicitly expressed by the programmer. List accounts = new LinkedList ();... print(accounts);

29 ©SoftMoore ConsultingSlide 29 Using Generic Methods We can solve the copy problem using a generic method static void copy(T[] source, Collection destination) { for (T o : source) destination.add(o); // Correct } Calling the generic method List accts = new LinkedList ();... BankAccount[] actArray = new BankAccount[100];... copy(actArray, accts); // T inferred to be BankAccount

30 ©SoftMoore ConsultingSlide 30 Using Legacy Code with Generics When a generic type like List is used without a type parameter, it is a raw type (type Object ). Using a raw type generates an unchecked warning, not an error. List list = new ArrayList(); // use only for compatibility // with legacy code list.add("Hello"); list.add(new Date()); The programmer is responsible for checking that the code is correct.


Download ppt "©SoftMoore ConsultingSlide 1 Generics “Generics constitute the most significant change in the Java programming language since the 1.0 release.” – Cay Horstmann."

Similar presentations


Ads by Google