Skip to content

Instantly share code, notes, and snippets.

@iande
Created May 9, 2012 14:34
Show Gist options
  • Save iande/2644926 to your computer and use it in GitHub Desktop.
Save iande/2644926 to your computer and use it in GitHub Desktop.
Why generic type checking is slightly different...
public class Box<T> {
private T whatsInTheBox;
// Creates a new box that holds nothing of value
public Box() { this(null); }
// Creates a new box that holds the given T instance.
public Box(T store) {
this.set(store);
}
// Gets the T instance stored in the box
public T get() { return this.whatsInTheBox; }
// Stores a T instance in the box
public void set(T store) {
this.whatsInTheBox = store;
}
}
// Note: this code is not valid, just meant to serve as an illustration
// of why type checking seems to differ when passing around Generics.
public class GenericBomb {
public static void takeANumber(Number n) {
// This is fine because `doubleValue` is declared in the `Number` class.
double dVal = n.doubleValue();
// This is not fine because `compareTo` is from the `Integer` class,
// and this method sees `n` only as a `Number`.
n.compareTo(new Integer(3));
}
public static void stuffDoubleInBox(Box<Number> box) {
// This code is valid, a "Box that holds a Number" can "hold" an
// instance of Double without any problem. However, if the compiler
// allowed all of this code to compile, it would blow up at runtime
// because we're trying to stuff a `Double` instance into a box that
// holds an `Integer` instance.
box.set(new Double(3.0));
}
public static void stuffNumberInBox(Number n, Box<Number> box) {
// This code is also valid, but if the compiler allowed it, it
// would blow up at runtime because we're trying to stuff a `Float`
// instance into a box that holds an `Integer` instance.
box.set(n);
}
public static void main(String[] args) {
Integer myInt = new Integer(4);
// myBox is an instance of `Box` that "holds" an instance of `Integer`
Box<Integer> myBox = new Box<Integer>();
// Even though we are passing an `Integer` instance, the method sees it as a `Number` instance.
takeANumber(myInt);
// Even though we are passing a "Box that holds an Integer", the method would see it as
// a "Box that holds a Number" (if the compiler allowed this sort of thing.)
stuffDoubleInBox(myBox);
// And again, this isn't allowed because of how the type system handles Generics.
stuffNumberInBox(new Float(0.3f), myBox);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment