I have a sealed interface that permits 3 types.
sealed interface Parent permits ChildA, ChildB, ChildC {}
record ChildA(long num) implements Parent {}
record ChildB(long num) implements Parent {}
record ChildC(long num) implements Parent {}
I want to get the constructor of each type, so I tried the following.
Parent.class.getPermittedSubclasses();
However, the return type of getPermittedSubclasses()
is Class<?>
. Why would it not be Class<? extends Parent>
? Sealed interfaces are a brand new feature that do not have any dependencies. So why artificially restrict the return type in a way that makes the method less usable?
If the method returned Class<? extends Parent>
, I could turn around and do the following.
Class<? extends Parent> clazz = Parent.class.getPermittedSubclasses();
Class<Long> constructorParameter = Long.class;
Constructor<? extends Parent> constructor = clazz.getConstructor(constructorParameter);
Parent p = constructor.newInstance();
Now to be clear, I can get past this by doing @SuppressWarnings("unchecked")
, and then just forcefully casting the value to be exactly what I want, but obviously, that is not ideal at all.
As is, this is just arbitrarily limiting for no benefit that I can see. So can someone explain why this is the case?
The reason for this were apparently type safety concerns regarding generic arrays, see JDK-8246278 and the referenced mailing list post.
Though arguably that decision is rather questionable because it sacrifices usability for a rather contrived corner case (which most likely will never occur in regular code).
Additionally there are other existing methods such as
Class.getTypeParameters()
with return typeTypeVariable<Class<T>>[]
which suffer from the same (contrived) issue (there also exists the "Won't Fix" issue JDK-5063716 for this).