At the time of compilation, the compiler does not know what arg2 is (and it can be anything), so the compiler cannot rule out that casting can work and must trust the programmer.
I would say that the compiler does not know what T will be. It can be, for example, Object , in which case the throw will be legal. Designers chose to allow, possibly illegal throws, to ban, possibly legal throws in this case.
Another problem is that the compiler cannot create the actual "cast to T " because the JVM only has the "cast to specific class" command. Thus, the listing seems to be doing well at runtime.
If you really want to have a marked amount, you can achieve this by passing Class<T> as an additional argument:
static <T> void f1(Base arg1, Class<T> clazz) { T loc = clazz.cast(arg1);
In your case, you can write
static <T> void f1(Base arg1, T arg2) { T loc = (T) arg2.getClass().cast(arg1); System.out.println(loc.getClass().getName()); }
It is instructive to find out in which cases it differs from the previous code.
source share