Generics CSCI 201 Principles of Software Development Jeffrey

  • Slides: 18
Download presentation
Generics CSCI 201 Principles of Software Development Jeffrey Miller, Ph. D. jeffrey. miller@usc. edu

Generics CSCI 201 Principles of Software Development Jeffrey Miller, Ph. D. jeffrey. miller@usc. edu

Outline • Generics – Generic Classes – Generic Methods • Program 2/18 USC CSCI

Outline • Generics – Generic Classes – Generic Methods • Program 2/18 USC CSCI 201 L

Generics Overview ▪ Generics were introduced in Java version 5. 0 in 2004 ▪

Generics Overview ▪ Generics were introduced in Java version 5. 0 in 2004 ▪ Generics allow you to parameterize types › This is similar to templates in C++ ▪ A class or method can be defined with generic types that the compiler can replace with concrete types ▪ Generics allow type errors to be detected at compile time rather than runtime › › 1 2 3 4 A generic class or method allows you to specify allowable types of objects that the class or method can use, and if you attempt to use an incompatible type, a compile-time error occurs Before generics, methods that took multiple types had to take a parent type (usually Object), but then any variable that inherits from that class could be passed in, not just a subset of them, potentially causing a runtime error public interface Comparable { public int compare. To(Object o); . . . } • Generics – Generic Classes 1 2 3 4 public interface Comparable<T> { public int compare. To(T o); . . . } USC CSCI 201 L 3/18

Generic Instantiation ▪ To create a class or interface that takes a generic, include

Generic Instantiation ▪ To create a class or interface that takes a generic, include an identifier (by convention, a single capital letter) in angle brackets immediately following the name of the class or interface › › 1 2 3 4 5 6 7 8 9 10 11 Use that identifier in any variable declaration or return type in the class When you create an instance of that class, you will need to parameterize the class with a concrete class to use in place of that generic • Note: You must use a concrete class and not a primitive data type or abstract class public class Test<T> { public void print(T t) { System. out. println(t); } public static void main(String args[]) { Test<String> t = new Test<String>(); t. print("Hello CSCI 201"); } } • Generics – Generic Classes USC CSCI 201 L 4/18

Using Generics ▪ Does this code compile? 1 2 3 4 5 6 7

Using Generics ▪ Does this code compile? 1 2 3 4 5 6 7 8 9 10 11 public class Test<T> { public void print(T t) { System. out. println(t); } public static void main(String args[]) { Test<String> t = new Test<String>(); t. print(33); } } • Generics – Generic Classes USC CSCI 201 L 5/18

Generics with Array. List ▪ The generic passed into an Array. List must be

Generics with Array. List ▪ The generic passed into an Array. List must be an object, not a primitive type › Casting is allowed though 1 2 3 4 5 6 7 8 9 10 11 12 13 import java. util. Array. List; public class Test { public static void main(String args[]) { Array. List<Integer> arr = new Array. List<Integer>(); arr. add(3); This is called autoboxing, which is a type arr. add(new Integer(4)); of casting that takes a primitive type and arr. add("5"); converts it to its wrapper object int num = arr. get(0); System. out. println("num = " + num); } } • Generics – Generic Classes USC CSCI 201 L 6/18

Generic Stack 1 2 3 4 5 6 7 8 9 10 11 12

Generic Stack 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import java. util. Array. List; public class Test<E> { private Array. List<E> list = new Array. List<E>(); public int get. Size() { return list. size(); } public E peek() { return list. get(get. Size()-1); } public void push(E o) { list. add(o); } public E pop() { E o = list. get(get. Size()-1); list. remove(get. Size()-1); return o; } • Generics – Generic Classes 19 public boolean is. Empty() { 20 return list. is. Empty(); 21 } 22 public static void main(String [] args) { 23 Test<String> stack 1 = new Test<String>(); 24 stack 1. push("CSCI 103"); 25 stack 1. push("CSCI 104"); 26 stack 1. push("CSCI 201"); 27 Test<Integer> stack 2 = new Test<Integer>(); 28 stack 2. push(103); 29 stack 2. push(104); 30 stack 2. push(201); 31 } 32 } USC CSCI 201 L 7/18

Multiple Generics 1 2 3 4 5 6 7 8 9 10 11 12

Multiple Generics 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import java. util. Array. List; 19 public class Generic. Stack<E, F> { 20 private Array. List<E> list = 21 new Array. List<E>(); 22 23 public int get. Size() { 24 return list. size(); 25 } 26 public E peek() { return list. get(get. Size()-1); 27 } 28 public void push(E o) { 29 list. add(o); 30 } 31 public E pop() { E o = list. get(get. Size()-1); 32 list. remove(get. Size()-1); 33 return o; 34 } 35 36 37 } • Generics – Generic Classes public boolean is. Empty() { return list. is. Empty(); } public void print(F f) { System. out. println(f); } public static void main(String [] args) { Generic. Stack<String, Double> stack 1 = new Generic. Stack<String, Double>(); stack 1. push("CSCI 103"); stack 1. push("CSCI 104"); stack 1. push("CSCI 201"); stack 1. print(3. 5); Generic. Stack<Integer, String> stack 2 = new Generic. Stack<Integer, String>(); stack 2. push(103); stack 2. push(104); stack 2. push(201); stack 2. print("Hello CSCI 201"); } USC CSCI 201 L 8/18

Generic Methods ▪ If you want to use a generic in a static method

Generic Methods ▪ If you want to use a generic in a static method within a class, the following syntax is used › This is because there is no instantiation needed to call a static method, so we needed to be able to parameterize the method call 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class Test { public static<T> void print(T [] list) { for (int i=0; i < list. length; i++) { System. out. print(list[i] + " "); } } public static void main(String[] args ) { Integer[] integers = {1, 2, 3, 4, 5}; String[] strings = {"London", "Paris", "New York"}; Test. <Integer>print(integers); Test. <String>print(strings); } } • Generics - Generic Methods USC CSCI 201 L 9/18

Bounded Generics ▪ You can specify that you want a generic type to be

Bounded Generics ▪ You can specify that you want a generic type to be a subtype of another type 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import java. io. Buffered. Reader; java. io. File. Reader; java. io. IOException; java. io. Reader; public class Test { public static<T extends Reader> void open. File(T t) throws IOException { Buffered. Reader br = new Buffered. Reader(t); String line = br. read. Line(); } public static void main(String[] args ) { try { Test. <File. Reader>open. File(new File. Reader(args[0])); } catch (IOException ioe) { System. out. println("exception: " + ioe. get. Message()); } } } • Generics - Generic Methods USC CSCI 201 L 10/18

Missing Generics ▪ If a class or method is parameterized and you leave off

Missing Generics ▪ If a class or method is parameterized and you leave off the generic instantiation, the class or method will be parameterized with the Object class › This is why you cannot use primitive types in generic instantiations › The following two lines are equivalent › This keeps backwards compatibility with previous versions of Java before serialization existed 1 Vector v = new Vector(); 2 Vector<Object> v = new Vector<Object>(); • Generics - Generic Methods USC CSCI 201 L 11/18

Subclass Generics ▪ Does the following code compile? 1 2 3 4 5 6

Subclass Generics ▪ Does the following code compile? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class Wild. Card. Demo { public static void main(String[] args ) { Generic. Stack<Integer> int. Stack = new Generic. Stack<Integer>(); int. Stack. push(1); // autoboxing int. Stack. push(2); // autoboxing int. Stack. push(-2); // autoboxing System. out. print("The max number is " + max(int. Stack)); } public static double max(Generic. Stack<Number> stack) { double max = stack. pop(). double. Value(); // Initialize max while (!stack. is. Empty()) { double value = stack. pop(). double. Value(); if (value > max) { max = value; } } return max; } } • Generics - Generic Methods USC CSCI 201 L 12/18

Wildcard Generics ▪ There are three types of wildcard generics › Unbounded wildcard –

Wildcard Generics ▪ There are three types of wildcard generics › Unbounded wildcard – written either as ? or ? extends Object › Bounded wildcard – written as ? extends T represents T or an unknown subtype of T › Lower-bound wildcard – written as ? super T denotes T or an unknown supertype of T ▪ Wildcard generics can be used on parameterized classes and parameterized methods • Generics - Generic Methods USC CSCI 201 L 13/18

Subclass Generics ▪ This code now compiles 1 2 3 4 5 6 7

Subclass Generics ▪ This code now compiles 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class Wild. Card. Demo { public static void main(String[] args ) { Generic. Stack<Integer> int. Stack = new Generic. Stack<Integer>(); int. Stack. push(1); // 1 is autoboxed into new Integer(1) int. Stack. push(2); int. Stack. push(-2); System. out. print("The max number is " + max(int. Stack)); } public static double max(Generic. Stack<? extends Number> stack) { double max = stack. pop(). double. Value(); // Initialize max while (!stack. is. Empty()) { double value = stack. pop(). double. Value(); if (value > max) { max = value; } } return max; } } • Generics - Generic Methods USC CSCI 201 L 14/18

Superclass Generics ▪ Does the following code compile? 1 2 3 4 5 6

Superclass Generics ▪ Does the following code compile? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Wild. Card. Demo 3 { public static void main(String[] args) { Generic. Stack<String> stack 1 = new Generic. Stack<String>(); Generic. Stack<Object> stack 2 = new Generic. Stack<Object>(); stack 2. push("Java"); stack 2. push(2); stack 1. push("Sun"); add(stack 1, stack 2); } public static<T> void add(Generic. Stack<T> s 1, Generic. Stack<T> s 2) { while (!s 1. is. Empty()) { s 2. push(s 1. pop()); } } } • Generics - Generic Methods USC CSCI 201 L 15/18

Superclass Generics (cont. ) ▪ The following code now compiles 1 2 3 4

Superclass Generics (cont. ) ▪ The following code now compiles 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Wild. Card. Demo 3 { public static void main(String[] args) { Generic. Stack<String> stack 1 = new Generic. Stack<String>(); Generic. Stack<Object> stack 2 = new Generic. Stack<Object>(); stack 2. push("Java"); stack 2. push(2); stack 1. push("Sun"); add(stack 1, stack 2); } public static<T> void add(Generic. Stack<T> s 1, Generic. Stack<? super T> s 2) { while (!s 1. is. Empty()) { s 2. push(s 1. pop()); } } } • Generics - Generic Methods USC CSCI 201 L 16/18

Outline • Generics – Generic Classes – Generic Methods • Program 17/18 USC CSCI

Outline • Generics – Generic Classes – Generic Methods • Program 17/18 USC CSCI 201 L

Program ▪ Create a sorting program that allows any type of number to be

Program ▪ Create a sorting program that allows any type of number to be taken as a parameter and it will still sort the array. The user should be prompted to enter the type of variables he wants. (i) Integer (f) Float (d) Double What type of array would you like to sort? f Original array: 3. 4, 1. 2, 5. 2, 6. 3, 2. 9 Sorted array: 1. 2, 2. 9, 3. 4, 5. 2, 6. 3 • Program USC CSCI 201 L 18/18