public class Box<T> {
private T t;
public Box(T t){
this.t = t;
}
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
public static void main(String[] args) {
Box<Integer> b = new Box(new String("may be"));
System.out.println(b.get()); // successfully print out "may be"
System.out.println(b.get().getClass()); // error
}
}
This code gives a runtime error:
exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
b.get()
not triggering a runtime error?To be more precise: why is the compiler inserting a checkcast
instruction into the bytecode only for the second get()
(leading to the exception)?
Box rawBox = new Box(); Therefore, Box is the raw type of the generic type Box<T>. However, a non-generic class or interface type is not a raw type. The warning shows that raw types bypass generic type checks, deferring the catch of unsafe code to runtime.
A Generic Version of the Box Class To update the Box class to use generics, you create a generic type declaration by changing the code "public class Box" to "public class Box<T>". This introduces the type variable, T, that can be used anywhere inside the class.
Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.
Implementing generics into your code can greatly improve its overall quality by preventing unprecedented runtime errors involving data types and typecasting.
Please note:
get()
is used for println(Object)
: in other words: the receiving side expects an Object, and that "condition" will always be true.As background, one can look into the Java Language Specification, chapter 5.52:
The cast is a checked cast.
Such a cast requires a run-time validity check. If the value at run time is null, then the cast is allowed. Otherwise, let R be the class of the object referred to by the run-time reference value, and let T be the erasure (§4.6) of the type named in the cast operator. A cast conversion must check, at run time, that the class R is assignment compatible with the type T, via the algorithm in §5.5.3.
respectively chapter 5.53 Checked Casts at Run Time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With