Why does Class.getPermittedSubclasses() return Class<?>[] and not Class<? extends T>[]

189 views Asked by At

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?

1

There are 1 answers

1
Marcono1234 On BEST ANSWER

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 type TypeVariable<Class<T>>[] which suffer from the same (contrived) issue (there also exists the "Won't Fix" issue JDK-5063716 for this).