Download presentation
Presentation is loading. Please wait.
Published byCarmella Norman Modified over 6 years ago
1
CIS265/506 Cleveland State University – Prof. Victor Matos
Chapter 19 Generics CIS265/506 Cleveland State University – Prof. Victor Matos Adapted from: Introduction to Java Programming: Comprehensive Version, Eighth Edition by Y. Daniel Liang
2
Why Do You Get a Warning? import java.util; public class ShowUncheckedWarning { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add("Java Programming"); } To understand the compile warning on this line, you need to learn JDK 1.5 generics.
3
Fixing the Warning No compile warning on this line.
import java.util; public class DoNotShowUncheckedWarning { public static void main(String[] args) { ArrayList<String> list = new ArrayList<String>(); list.add("Java Programming"); } No compile warning on this line.
4
What is Generics? Generics is the capability to parameterize types.
With this feature, you can define a class or a method to operate on generic types that the compiler at a later time can substituted with some given concrete types. Example You may define a generic queue that stores either integer numbers or company clients. The queue’s behavior should be the same regardless of the type of items currently stored.
5
Why Generics? The key benefit of generics is to enable error detection at compile time rather than at runtime. A generic class or method permits you to specify allowable types of objects that the class or method may work with. If you attempt to use the class or method with an incompatible object, the compile error occurs For example, a queue of company clients can not accept the insertion of geometric figures.
6
Generic Type Generic Instantiation Runtime error
Benefit: New generic type detects errors at compile time Compile error
7
Generics Type Naming Convention
Commonly used type parameter names are: E – Element K – Key (Used in <key,value> notation) N – Number T – Type V – Value
8
Generic ArrayList Old references to Object types are changed to generic E types in the new ArrayList class
9
Advantage: No Casting Needed
ArrayList<Double> list = new ArrayList<Double>(); list.add(5.5); // 5.5 is automatically converted to new Double(5.5) list.add(3d); // 3D is automatically converted to new Double(3.0) Double doubleObj = list.get(0); // No casting is needed double d = list.get(1); // Automatically converted to double
10
Example: Generic Stack Class
import java.util.ArrayList; public class GenericStack< E > { private ArrayList<E> list = new ArrayList<E>(); public int getSize() { return list.size(); } public E peek() { return list.get(getSize() - 1); public void push(E o) { list.add(o); public E pop() { E o = list.get(getSize() - 1); list.remove(getSize() - 1); return o; public boolean isEmpty() { return list.isEmpty(); Now you could create GenericStack<String> stk1 … or GenericStack<Circle> stk2 … and so on
11
Generic Methods public static void main(String[] args) {
String[] array1 = {"aaa", "bbb", "ccc" }; print1(array1); print2(array1); }// main // newer (and better) style using generics public static <E> void print1(E[] list) { for (int i = 0; i < list.length; i++) System.out.print(list[i] + " "); System.out.println(); } // old format using Objects public static void print2(Object[] list) { CONSOLE aaa bbb ccc aaa bbb ccc
12
Bounded Generic Type A generic type E that is specified as a subtype of another type is called bounded. Syntax is <E extends SomeOtherType> For example: <E extends GeometricObject> could be used to allow E to later on refer to either a Circle or a Rectangle.
13
Example: Bounded Generic Type
public static void main(String[] args) { Rectangle rectangle = new Rectangle(2, 2); Circle circle = new Circle(2); System.out.println ( rectangle.toString() ); System.out.println ( circle.toString() ); System.out.println ( "Same area? " + equalArea(rectangle, circle) ); }// main public static <E extends GeometricObject> boolean equalArea( E object1, E object2 ) { return object1.getArea() == object2.getArea(); } CONSOLE >>> Rectangle white created on Thu Feb 09 19:52:33 EST 2012 color: white and filled: false >>> Height: 2.0 Width: 2.0 Perimeter: 8.0 Area: 4.0 >>> Circle white >>> Radius: 2.0 Perimeter: Area: Same area? false
14
Raw Type and Backward Compatibility
ArrayList list = new ArrayList(); // this is roughly equivalent to ArrayList<Object> list = new ArrayList<Object>();
15
Raw Type is Unsafe // find a maximum object public class TestMyMax {
public static void main(String[] arg) { TestMyMax.max("Welcome", 23); } // return the maximum between two objects public static Comparable max( Comparable o1, Comparable o2 ) { if (o1.compareTo(o2) > 0) return o1; else return o2; CONSOLE Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at java.lang.String.compareTo(Unknown Source) at csu.matos.TestMyMax.max(TestMyMax.java:11) at csu.matos.TestMyMax.main(TestMyMax.java:6) at csu.matos.Driver.main(Driver.java:13)
16
Make it Safe – Check at Compile Time
// find a maximum object public class TestMyMax2 { public static void main(String[] arg) { TestMyMax2.max("Welcome", 23); } // Return the maximum between two objects public static < E extends Comparable<E> > E max( E o1, E o2 ) { if (o1.compareTo(o2) > 0) return o1; else return o2;
17
Wildcards are used to generalize types
A wildcard generic type has three possible forms ?, called an unbounded wildcard, is the same as ? extends Object ? extends T, called a bounded wildcard, represents T or an unknown subtype of T. ? super T, called a lower-bound wildcard, denotes T or an unknown supertype of T.
18
Generic Types and Wildcard Types
A and B represent classes or interfaces E represents a generic type parameter
19
Example1: Generic Types and Wildcard Types
public class WildCardDemo2 { public static void main(String[] args) { GenericStack<Integer> intStack = new GenericStack<Integer>(); intStack.push(1); // 1 is autoboxed into new Integer(1) intStack.push(2); intStack.push(3); print1(intStack); print2(intStack); } // Version1: prints objects and empties the stack (generic E) public static <E> void print1(GenericStack<E> stack) { while (!stack.isEmpty()) { System.out.print(stack.pop() + " "); // Version2: prints objects and empties the stack (wildcard ?) public static void print2(GenericStack<?> stack) { Equivalent code using (1) generic and (2) wildcard parameters
20
Example2: Generic Types and Wildcard Types
public class WildCardDemo3 { public static void main(String[] args) { GenericStack<String> stack1 = new GenericStack<String>(); stack1.push("Sun"); GenericStack<Object> stack2 = new GenericStack<Object>(); stack2.push(111); move(stack1, stack2); print(stack2); } public static <T> void move( GenericStack<T> stack1, GenericStack<? super T> stack2) { while (!stack1.isEmpty()) stack2.push(stack1.pop()); public static void print(GenericStack<?> stack) { while (!stack.isEmpty()) { System.out.print(stack.pop() + " "); First type T is String and second is a Supertype of T
21
Example2B: Generic Types and Wildcard Types
public static void main(String[] args) { GenericStack<Circle> stack1 = new GenericStack<Circle>(); stack1.push(new Circle(1)); stack1.push(new Circle(2)); stack1.push(new Circle(3)); GenericStack<GeometricObject> stack2 = new GenericStack<GeometricObject>(); move(stack1, stack2); print(stack2); } public static <T> void move(GenericStack<T> stack1, GenericStack<? super T> stack2) { while (!stack1.isEmpty()) stack2.push(stack1.pop()); public static void print(GenericStack<?> stack) { while (!stack.isEmpty()) { System.out.print(stack.pop() + " "); First type T is Circle and second is a Supertype of T
22
Erasure and Restrictions on Generics
Generics are implemented using an approach called type erasure. The compiler uses the generic type information to compile the code, but erases it afterwards. So the generic information is not available at run time. This approach enables the generic code to be backward-compatible with the legacy code that uses raw types. For example, the compiler checks whether generics is used correctly for the following code in (a) and translates it into the equivalent code in (b) for runtime use. The code in (b) uses the raw type.
23
Erasure and Restrictions on Generics
Restriction 1: Cannot Use new E() You cannot create an instance using a generic type parameter. The following statement is wrong: E object = new E(); Restriction 2: Cannot Use new E[] You cannot create an array using a generic type parameter. The following statement is wrong: E[] elements = new E[size]; Workaround: E[] elements = (E[]) new Object[ capacity]; Restriction 3: A Generic type parameter of a class is not allowed in a static context. The following fragment is wrong public class Test <E>{ public static void m(E o1) { // Illegal } } Restriction 4: Exception classes cannot be generic. Following is wrong public class MyException<T> extends Exception { }
24
Important Facts It is important to note that a generic class is shared by all its instances regardless of its actual generic type. GenericStack<String> stack1 = new GenericStack<String>(); GenericStack<Integer> stack2 = new GenericStack<Integer>(); Although GenericStack<String> and GenericStack<Integer> are two types, there is only one class GenericStack loaded into the JVM.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.