I try to get a switch case by class working using JDK17 Preview.
sealed class A permits X,Y{}
final class X extends A{}
final class Y extends A{}
public static <T extends A> List<T> switchByClass(Class<T> clazz) {
return switch (clazz) {
case Class<X> x-> xObjects();
case Class<Y> y-> yObjects();
default -> throw new IllegalArgumentException();
};
}
public static List<X> xObjects() {
return List.of(new X(), new X());
}
public static List<Y> yObjects() {
return List.of(new Y(), new Y());
}
For both cases I get compiler error, e.g. for first case: java.lang.Class<T>' cannot be safely cast to 'java.lang.Class<X>'
This is quite surprising as I expected that switch case logic just tries to cast in the background to find the correct match.
Any idea how to get matching by class working? (Matching by object types is not the point here). Is it a java limitation, like maybe class matching is not supported?
UPDATE:
I tried to use the class name instead, also not working.
"Constant expression required" at cases xName
, yName
. However, I don't see how xName, yName are not constant. As far as I understand they should be also compile time constant.
public static <T> List<T> switchByClassString(Class<T> clazz) {
final String xName = X.class.getName();
final String yName = Y.class.getName();
return switch (clazz.getClass().getName()) {
case xName -> (List<T>) xObjects();
case yName-> (List<T>) yObjects();
default -> throw new IllegalArgumentException();
};
}
UPDATE 2:
In the meantime I guess it is easier to be solved by OOP like:
interface A {
<T extends A> List<T> getObjects();
}
class X implements A {
@Override
public List<X> getObjects() { return List.of(new X(), new X());}
}
class Y implements A {
@Override
public List<Y> getObjects() { return List.of(new Y(), new Y());}
}