Short answer:
- The JVM specification prohibits throwing and catching parameterized exceptions, but does not care about the declaration. It does not even prohibit that it is simply impossible to represent a type parameter in bytecode, so the question is debatable.
- JLS forbids them to declare, because in any case you cannot use them.
Long answer:
The Java language specification says (ยง8.1.2) about the declaration of such a class:
This is a compile-time error if the general class is a direct or indirect Throwable subclass (ยง11.1.1).
This restriction is necessary because the catch mechanism of the Java virtual machine only works with non-generic classes.
And he talks about throwing an exception (ยง14.18):
The expression in the throw expression should mean either
1) a variable or value of a reference type that is assigned (ยง5.2) to the Throwable type, or
2) null reference or compile-time error.
An Expression reference type will always be a class type (since no interface types are assigned to Throwable) that is not parameterized (since the Throwable subclass cannot be general (ยง8.1.2)).
This restriction was added when generics were added to the Java language because they were not added to the JVM: only raw types exist on the JVM.
There is still information about a parameter of this type where the class is defined, but not where it is used! Regardless of the declaration of a parameterized exception, this is not possible at the JVM level :
try { throw new Foo<String>("test"); } catch(Foo<Int> e) {
The implementation of exception exclusion is that there is an exception table that specifies the bytecode ranges to view and the class associated with it. This class cannot have a type parameter, since there is no way to describe them in bytecode (JVM specification, ยงยง2.10 and ยง3.12).
Due to type erasure, the throw clause applies only to Foo , and these two catch methods become two entries in the exception table that belong to the Foo class, which is useless and impossible in any case. As a result, this syntax is not possible in the Java language, and you can only catch Foo .
And as a consequence of this, it becomes quite useless and potentially dangerous to be able to declare parameterized exceptions. Therefore, they were generally banned in this language, although the JVM itself does not care.