This variable declaration is incompatible.
Box<Integer> b = new Box(new String("may be")); :
The instantiated object is unprocessed, so the compiler gives a warning about this, but allows you to assign an unprocessed type to a common variable: Box<Integer> .
b.get() not interrupted since you are not assigning the result to a variable.
Thus, the compiler should not throw it on anything.
Try the following:
Integer value = b.get();
It will compile fine, but at runtime you will get the same exception as the JVM will try to pass an Integer value:
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
When called:
System.out.println(b.get().getClass());
Things are close to.
Why is the Integer class expected here?
At compile time, b declared as Box<Integer> b .
Therefore, the compiler knows that b parameterized by type Integer .
So yes, after compilation, the generic files are erased, but the compiler adds, however, some discards according to the declared code.
And here it is. You call getClass() on a variable parameterized with Integer .
But Class is a generic class: Class<T> .
So the cast to Integer was added by the compiler to match the Class<Integer> .
Of course, using generics both to declare variables and to instantiate:
Box<Integer> b = new Box<>(new String("may be"));
such inconsistency is not possible because the compiler is stopping you right now.