我试图弄清楚是否有办法避免此函数中未经检查的强制转换(使用 Java 7):
private static <O> ValueValidator<O> newForAlways(Always valid_orInvalid) {
@SuppressWarnings("unchecked")
ValueValidator<O> vldtr = (ValueValidator<O>)(valid_orInvalid == Always.VALID
? newForAlwaysValid()
: newForAlwaysInvalid());
return vldtr;
}
以下是返回的两个函数的签名:
private static <O> ValueValidator<O> newForAlwaysValid() {
private static <O> ValueValidator<O> newForAlwaysInvalid() {
(这是Always
枚举,它只是一个布尔替换:
enum Always {VALID, INVALID;};
)
所有三个函数都具有相同的返回类型,并包含无界泛型。这两个问题解释了为什么会发生这种情况,尽管两者都是关于有界泛型的:
- 为什么三元运算符不喜欢带有有界通配符的泛型类型?
- 在 Java 8 中使用三元运算符的泛型编译错误,但在 Java 7 中不是
所以即使这有效
ValueValidator<Integer> intVldtr = Test.<Integer>newForAlwaysValid();
这不会:
private static <O> ValueValidator<O> newForAlways(Always valid_orInvalid) {
return (valid_orInvalid == Always.VALID
? <O>newForAlwaysValid()
: <O>newForAlwaysInvalid());
}
C:java_codeTest.java:15: error: illegal start of expression
? <O>newForAlwaysValid()
...and 8 more similar errors...
这也不是:
private static <O> ValueValidator<O> newForAlways2(Always valid_orInvalid) {
return (valid_orInvalid == Always.VALID
? newForAlwaysValid()
: newForAlwaysInvalid());
}
C:java_codeTest.java:15: error: incompatible types
? newForAlwaysValid()
^
required: ValueValidator<O>
found: ValueValidator<Object>
where O is a type-variable:
O extends Object declared in method <O>newForAlways2(Always)
所以,重复这个问题:除了未经检查的演员阵容之外,还有其他选择吗?(我使用的是Java 7。
SSCCE:
public class Test {
public static void main(String[] ignored) {
ValueValidator<Integer> intVldtr = Test.<Integer>newForAlwaysValid();
intVldtr = Test.<Integer>newForAlways(Always.VALID);
}
private static <O> ValueValidator<O> newForAlways(Always valid_orInvalid) {
@SuppressWarnings("unchecked")
ValueValidator<O> vldtr = (ValueValidator<O>)(valid_orInvalid == Always.VALID
? newForAlwaysValid()
: newForAlwaysInvalid());
return vldtr;
}
private static <O> ValueValidator<O> newForAlwaysValid() {
return (new AlwaysValid<O>());
}
private static <O> ValueValidator<O> newForAlwaysInvalid() {
return (new AlwaysInvalid<O>());
}
}
enum Always {VALID, INVALID;};
abstract class ValueValidator<O> {
public abstract boolean isValid(O to_validate);
}
class AlwaysValid<O> extends ValueValidator<O> {
public boolean isValid(O to_validate) {
return true;
}
}
class AlwaysInvalid<O> extends ValueValidator<O> {
public boolean isValid(O to_validate) {
return false;
}
}
你可以做
ValueValidator<O> vldtr = valid_orInvalid == Always.VALID
? Test.<O>newForAlwaysValid()
: Test.<O>newForAlwaysInvalid();
所以你已经知道在 Java 7 中使用条件运算符进行泛型类型参数推理存在问题,该问题已在 Java 8 中修复。只是为了解决您的问题,您可以使用显式类型参数。
好吧,您已经尝试过这样做,但这是无效的语法。使用显式类型参数时,始终必须使用对象类型或类类型限定方法调用。因此,请将您的方法更改为:
private static <O> ValueValidator<O> newForAlways(Always valid_orInvalid) {
ValueValidator<O> vldtr = valid_orInvalid == Always.VALID
? Test.<O>newForAlwaysValid()
: Test.<O>newForAlwaysInvalid();
return vldtr;
}