使用 JDK17 在类上切换大小写

发布于 01-11 20:18 字数 1832 浏览 7 评论 0原文

我尝试使用 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());
    }

对于这两种情况,我都会收到编译器错误,例如第一种情况:java.lang.Class'无法安全地转换为 'java.lang.Class'

这非常令人惊讶,因为我预计 switch case 逻辑只是尝试在后台进行转换以找到正确的匹配项。

知道如何通过班级工作进行匹配吗? (按对象类型匹配不是这里的重点)。这是java的限制吗,比如可能不支持类匹配?

更新:

我尝试使用类名,但也不起作用。 在 xNameyName 情况下“需要常量表达式”。但是,我不明白 xName, yName 为何不是恒定的。据我了解,它们也应该是编译时间常数。

        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();
        };
    }

更新 2:

与此同时,我想通过 OOP 更容易解决,例如:

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());}
}

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());}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文