在三元中使用无界泛型静态函数时如何避免未经检查的强制转换



我试图弄清楚是否有办法避免此函数中未经检查的强制转换(使用 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;
}

最新更新