我试图避免显式地从方法中强制返回。
如果我在编译时静态地指定类,那么我所拥有的效果很好,但是我更希望在运行时从枚举类型中获取该类。
public enum Type {
SOME_TYPE(Clazz.class),
;
private Type(Class<?> clazz) {
this.clazz = clazz;
}
private final Class<?> clazz;
public Class<?> getClazz() {
return this.clazz;
}
}
public class Foo {
private Foo() {}
public static <T> T doSomething(Class<T> clazz, String input) {
// ...
final Object obj = someProcess(input);
return clazz.cast(obj);
}
}
public class Bar {
public void stuff() {
// does not work without explicit casting to SomeClass
// compiler error
Clazz sc = Foo.doSomething(Type.SOME_TYPE.getClazz(), someInputData);
// this does work, without an explicit cast
Clazz sc2 = Foo.doSomething(Clazz.class, someInputData);
}
}
我感觉这不可能动态地进行,因为编译器无法确定getClazz()
方法将返回什么类。
我该如何做?
答案 0 :(得分:2)
我试图避免显式地从方法中强制返回。
当前,编译器无法从中推断任何内容
Type.SOME_TYPE.getClazz()
因为此表达式引用了用通配符键入的Class
:
private final Class<?> clazz;
public Class<?> getClazz() {
return this.clazz;
}
编译器如何猜测需要将其强制转换为SomeClass
?
枚举中定义的Class
绝对是泛型。
我认为这种设计不适合您的需求。
如果要避免任何强制转换,请替换
Type.SOME_TYPE.getClazz()
通过将要显示的类显式地返回给方法的方法:
SomeClass.class
例如
SomeClass sc = Foo.doSomething(SomeClass.class, someInputData);
答案 1 :(得分:1)
泛型允许您省略强制转换如果,编译器可以证明该值将是该操作的兼容类型。
在您工作的sc2
示例中,编译器可以看到您正在为Class
类传递Class
对象。 doSomething
承诺将返回其类型与类型标记相匹配的对象(编译器也会对此进行验证),因此可以证明doSomething
在这种情况下将返回一个Class
实例;不需要演员。
但是,由于动态选择Class
实例的性质,编译器无法证明类型将与此分配兼容。就编译器所知,您可能会加载代码,这些代码将更改将提供的Class
作为类型标记,并更改返回的内容。由于可能存在不兼容的分配,这将引发异常,因此Java规则需要显式强制转换。
从逻辑上讲,实际上没有办法完全按照设计来完成您要问的事情。
在不了解您要完成的目标的情况下很难提出替代方案,因为任何替代方法都会有局限性,我不知道哪种替代方法可以接受。当然,最简单的情况是是否存在(或可能)有用的通用基类或接口来处理您可能返回的所有事物;但我想如果是这样的话,您就不会考虑这种设计。