Upload
marvin-knight
View
216
Download
0
Embed Size (px)
Citation preview
Generics
DCS – SWC 2
Generics
• In many situations, we want a certain functionality to work for a variety of types
• Typical example: we want to be able to store elements of a certain type in a container, say an ArrayList
• This ability does not pose any special requirements on the type itself
DCS – SWC 3
Generics
public class ArrayList
{
public ArrayList() {…}
public void add(Object e) {…}
}
DCS – SWC 4
Generics
• Since all classes inherit from Object, this will work – in principle
• However, there is nothing to prevent us from storing elements of different types in the same ArrayList
• Will complicate processing of the elements
• Risk for errors at run-time
DCS – SWC 5
Generics
• A better (safer) solution is to use Generics
• In a generic class, one or more type parameters are included in the definition
• Example is the well-known ArrayList<E>
DCS – SWC 6
Generics
public class ArrayList<E>
{
public ArrayList() {…}
public void add(E e) {…}
}
E is the type parameter
DCS – SWC 7
Generics
• When we wish to use the class, we must instantiate it with a concrete type:– ArrayList<BankAccount>– ArrayList<Car>
• We can use the ArrayList for all types, BUT we cannot put two objects of different types into the same ArrayList
DCS – SWC 8
Creating a generic class
• Creating a generic class is almost like creating an ordinary class
• However, one or more of the types are turned into type parameters
• Consider a class for storing a pair of objects, which may have different types
Pair<String, Car>
DCS – SWC 9
Creating a generic classpublic class Pair<T,S>
{
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;}
}
DCS – SWC 10
Creating a generic method
• An ordinary method inside a class usually does not need a type parameter
• Type parameter for class is used
• However, this is not the case for static methods:
public static <E> void print(E[] a)
DCS – SWC 11
Creating a generic method
• When invoking a generic method, we do not need to specify a type parameter:Car[] carList;
ArrayUtil.print(carList);
• The compiler can figure out what the concrete type of the parameter is
DCS – SWC 12
Type constraints
• Sometimes, we will only allow types that fulfill some properties
• Consider the min method:
public static <E> E min(E a, E b)
{
if (a < b) return a;
else return b;
}
DCS – SWC 13
Type constraints
• The previous code will only work for types that can be compared
• Type must implement the Comparable interface
• We must constrain the type parameter to fulfill this property
DCS – SWC 14
Type constraints
public static <E extends Comparable> E
min(E a, E b)
{
if (a < b) return a;
else return b;
}
• See Advanced Topic 17.1 for more advanced issues on type constraints
DCS – SWC 15
Under the hood
• How does the Java Virtual Machine handle generics…?
• It substitutes the type variables with a concrete type, depending on the type constraints
DCS – SWC 16
Under the hood
public class Pair<T, S>
{
private T first;
private S second;
public Pair(T first, S second) {...}
public T getFirst() {return first;}
public S getSecond() {return second;}
}
DCS – SWC 17
Under the hood
public class Pair
{
private Object first;
private Object second;
public Pair(Object first, Object second) {...}
public Object getFirst() {return first;}
public Object getSecond() {return second;}
}
DCS – SWC 18
Under the hood
• But will that always work…?
• Yes, because the compiler has checked that all generic types are used correctly
• It does however impose some limitations on the code in generic methods:
E e = new E();
• This is illegal…(why)?
DCS – SWC 19
Under the hood
• Why does it work like that?
• Enables pre-generics code to work together with code using generics
• Does it matter in practice?
• Not much, but it explains why some perhaps not-so-obvious limitations exist