Java 枚举实现接口 Class<T> return 类型

Java enum implements interface with Class<T> return type

好的,乖一点。

这是一个实现接口的枚举,其方法 return 是一个 'raw type',它在接口中的 getCaste() 方法上给我一个警告。

public enum Thing implements HasCaste {

    Type1 {
        @Override
        public Class getCaste() {
            return String.class;
        }
    };
}

interface HasCaste {
    public Class getCaste();
}

如果我将接口的方法更改为:

public <T> Class<T> getCaste();

它更改为 Type1 方法签名上的未检查警告。如果我然后将 Type1.getCaste() 的签名更改为:

public <T> Class<T> getCaste()

然后 return 出现类型不兼容错误,因为 Class<String> 无法转换为 Class<T>。如果我随后将 return 更改为 (Class<T>) String.class,我们将收到未经检查的强制转换警告。

有没有办法在没有警告的情况下执行此操作?

编辑:

抱歉,我之前没有添加这个,但这样做会很好:

  , Type2 {
        @Override
        public Class getCaste() {
            return Integer.class;
        }
    };

正如在 中确定的那样,您不能使用 enum 来做到这一点,只能通过实际上是 class 的模拟枚举来做到这一点。

public abstract class Thing<T> implements HasCaste<T> {
    public static final Thing<String> Type1 = new Thing<String>() {
        @Override
        public Class<String> getCaste() {
            return String.class;
        }
    };
    public static final Thing<Integer> Type2 = new Thing<Integer>() {
        @Override
        public Class<Integer> getCaste() {
            return Integer.class;
        }
    };

    private Thing() {
    }
}

如您所见,那不是 enum。仅仅 enum 是不可能的,因为枚举不能有类型参数。

p.s.: 如果你觉得这有帮助,请查看 以获得更完整的解释,毕竟我是从他那里学到的:)

您可以不指定返回的 class 的类型参数:

public enum Thing implements HasCaste {

    Type1 {
        @Override
        public Class<String> getCaste() {
            return String.class;
        }
    }, Type2 {
        @Override
        public Class<Integer> getCaste() {
            return Integer.class;
        }
    };
}

interface HasCaste {
    public Class<?> getCaste();
}

假设您想定义几个不同的 "typed" 枚举常量,那么可以这样做:

interface HasCaste {
    public Class<?> getCaste();
}

public enum Thing implements HasCaste<?> {

    Type1(String.class),
    Type2(Integer.class);

    public final Class<?> clazz;

    private Thing(Class<?> clazz) {
        this.clazz = clazz;
    }

    @Override
    public Class<?> getCaste() {
        return clazz;
    }
}

然后将输入延迟到将来使用 getCaste。枚举的主要特征是封闭的值域;必须在 class.

中列出所有可能的值