Java Generics — Know the power of generics
public class Box
T just can’t be any of the primitive data types
/** * Generic version of the Box class. */
public class Box {
private T t; // T stands for “Type”
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
}
Invocation : Box integerBox = new Box();
An invocation of a generic type is generally known as a parameterized type
If you try adding an incompatible type to the box, such as String, compilation will fail, alerting you to what previously would have been a runtime bug:
During compilation, all generic information will be removed entirely, leaving only Box.class on the filesystem => TypeErasure
Type parameters can also be declared within method and constructor signatures to create generic methods and generic constructors
public void inspect(U u){
System.out.println(“T: ” + t.getClass().getName());
System.out.println(“U: ” + u.getClass().getName());
}
Calling the method: integerBox.inspect(“some text”);
Type inference, allows you to invoke a generic method as you would an ordinary method, without specifying a type between angle brackets.
There may be times when you’ll want to restrict the kinds of types that are allowed to be passed to a type parameter. For example, a method that operates on numbers might only want to accept instances of Number or its subclasses. This is what bounded type parameters are for
To declare a bounded type parameter, list the type parameter’s name, followed by the extends keyword, followed by its upper bound, which in this example is Number
public void inspect(U u){
System.out.println(“T: ” + t.getClass().getName());
System.out.println(“U: ” + u.getClass().getName());
}
To specify additional interfaces that must be implemented, use the & character, as in:
You can perform a generic type invocation, passing Number as its type argument, and any subsequent invocation of add will be allowed if the argument is compatible with Number:
Box box = new Box();
box.add(new Integer(10)); // OK
box.add(new Double(10.1)); // OK
In generics, an unknown type is represented by the wildcard character “?”.
To specify a cage capable of holding some kind of animal:
Cage someCage = …;
This is an example of a bounded wildcard, where Animal forms the upper bound of the expected type
Note: It’s also possible to specify a lower bound by using the super keyword instead of extends. The code , therefore, would be read as “an unknown type that is a supertype of Animal, possibly Animal itself”. You can also specify an unknown type with an unbounded wilcard, which simply looks like . An unbounded wildcard is essentially the same as saying
When a generic type is instantiated, the compiler translates those types by a technique called type erasure — a process where the compiler removes all information related to type parameters and type arguments within a class or method. Type erasure enables Java applications that use generics to maintain binary compatibility with Java libraries and applications that were created before generics.
For instance, Box is translated to type Box, which is called the raw type — a raw type is a generic class or interface name without any type arguments. This means that you can’t find out what type of Object a generic class is using at runtime
Type erasure exists so that new code may continue to interface with legacy code
Filed under: Uncategorized