Generic Classes and Methods: A Deeper Look Week 5- part A
Dr Mohammed Bahja [email protected] https://www.cs.bham.ac.uk/~bahjam/ Before we start
Ø Attendance code of today Ø In-class test ( week 6 –Friday) Ø No WS 4 (you will start the project a week early) Ø Groups for group project. Lecture Objective
To develop a thorough understanding of generic programming and how generic classes and methods can be used to provide simpler and elegant solutions Lecture Outline
Ø Objective of generic programming Ø How implement generic classes and methods Ø The execution of generic methods Ø Raw Type and Backward Compatibility Ø Overloading Generic Methods Ø The relationship between generic types and inheritance Ø Wildcards in Methods That Accept Type Parameters Ø Wildcards Types Why Do You Get a Warning?
Ø To understand the compile warning on line 6 & 7, you need to learn generics. The Warning?
ArrayList list = new ArrayList();
list.add("Java Programming"); Compile-time type safety
Ø Detect type mismatches at compile time—known as compile- time type safety. Ø Generic methods and generic classes provide the means to create type safe general models. Overloaded methods
Ø Overloaded methods are often used to perform similar operations on different types of data. Ø We can use Overloaded methods to print -for example- arrays of different types. But how many methods you need to create ? Overloaded methods (Cont’d) Ø Method for each data type Implementation and Compile-Time Translation Ø If the operations performed by several overloaded methods are identical for each argument type, the overloaded methods can be more conveniently coded using a generic method. Ø You can write a single generic method declaration that can be called with arguments of different types them the compiler handles each method call appropriately. What is Generics?
Ø Generic programming: creation of programming constructs that can be used with many different types. Ø In Java, achieved with inheritance or with type variables Ø The type variable denotes the element type
public class ArrayList
Ø You can define a class or a method with generic types that can be substituted using concrete types by the compiler. Why Generics?
Ø The key benefit of generics is to enable errors to be detected 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, a compile error occurs. Type Variables
Ø Can be instantiated with class or interface typesArrayList
Ø Cannot use a primitive type as a type variableArrayList
Ø Use corresponding wrapper class insteadArrayList
package java.lang; package java.lang;
public interface Comparable { public interface Comparable
(a) Prior to JDK 1.5 (b) JDK 1.5
Comparable c = new Date(); Comparable
(a) Prior to JDK 1.5 (b) JDK 1.5
Runtime error Compile error Safer and easier to read (Cont’d)
Ø Impossible to add a String into an ArrayList
ArrayList
Double doubleObject = list.get(0); // No casting is needed double d = list.get(1); // Automatically converted to double Raw Type and Backward Compatibility
Ø When generics were introduced into Java, several classes were updated to use generics. Ø Raw types refer to using a generic type without specifying a type parameter. For example, List is a raw type, while List
Ø What is the output of the code below if we call Max.max("Welcome", 23); ?
// Max.java: Find a maximum object public class Max { /** Return the maximum between two objects */ public static Comparable max(Comparable o1, Comparable o2) { if (o1.compareTo(o2) > 0) return o1; else return o2; } } Make it Safe
Ø What would you change to make it safe ?
// Max1.java: Find a maximum object public class Max1 { /** Return the maximum between two objects */ public static
Ø The concept of a data structure, such as a stack, can be understood independently of the element type it manipulates.
Ø Generic classes provide a means for describing the concept of a stack (or any other class) in a type-independent manner.
Ø These classes are known as parameterized classes or parameterized types because they accept one or more type parameters.
public class Stack
Ø Generic method: method with a type variable Ø Can be defined inside ordinary and generic classes Ø All generic method declarations have a type-parameter section (< T > in this example) delimited by angle brackets that precedes the method’s return type. Ø Cannot replace type variables with primitive types e.g.: cannot use the generic print method to print an array of type int[] Good practice Overloading Generic Methods
Ø A generic method may be overloaded like any other method. Ø A class can provide two or more generic methods that specify the same method name but different method parameters. Ø A generic method can also be overloaded by nongeneric methods. Ø When the compiler encounters a method call, it searches for the method declaration that best matches the method name and the argument types specified in the call—an error occurs if two or more overloaded methods both could be considered best matches. Common Error Wildcards in Methods That Accept Type Parameters Ø Suppose that you’d like to implement a generic method sum that totals the numbers in a List. Ø You’d begin by inserting the numbers in the collection. Ø The numbers would be autoboxed as objects of the type-wrapper classes— any int value would be autoboxed as an Integer object, and any double value would be autoboxed as a Double object. Ø We’d like to be able to total all the numbers in the List regardless of their type. Ø For this reason, we’ll declare the List with the type argument Number, which is the superclass of both Integer and Double. Ø In addition, method sum will receive a parameter of type List
Types inheritance
Ø In the previous example, it’s not valid to have List
Object List
Object Number List
Double List
True False True Upper Bounded Wildcards
Ø Given that method sum can total the elements of a List of Numbers, you might expect that the method would also work for Lists that contain elements of only one numeric type, such as List
Ø To create a more flexible version of the sum method that can total the elements of any List containing elements of any subclass of Number we use wildcard-type arguments. Ø Wildcards enable you to specify method parameters, return values, variables or fields, and so on, that act as supertypes or subtypes of parameterized types. Ø Imethod sum’s parameter can be declared with the type: List Ø A wildcard-type argument is denoted by a question mark (?), which by itself represents an “unknown type.” Ø In this case, the wildcard extends class Number, which means that the wildcard has an upper bound of Number. Ø Thus, the unknown-type argument must be either Number or a subclass of Number.
Upper Bounded Wildcards(Cont’d) Ø Because the wildcard (?) in the method’s header does not specify a type-parameter name, you cannot use it as a type name throughout the method’s body Ø You could, however, declare method sum as follows: public static
public static MyList getList() { // ... return MyList
Ø What will happen if we pass list of type Double ? Ø Double is not the superclass of Integer Unbounded Wildcard Ø Note: You can specify an upper bound for a wildcard, or you can specify a lower bound, but you cannot specify both. Ø The unbounded wildcard type is specified using the wildcard character (?), for example, List. This is called a list of unknown type. Ø There are two scenarios where an unbounded wildcard is a useful approach: Ø If you are writing a method that can be implemented using functionality provided in the Object class. Ø When the code is using methods in the generic class that don't depend on the type parameter. For example, List.size or List.clear. Ø In fact, Class is so often used because most of the methods in Class