通用 JavaBeanObjectProperty 的未检查分配错误,但 ReadOnlyJavaBeanObjectProperty 没有

Unchecked Assignment error for generic JavaBeanObjectProperty but not for ReadOnlyJavaBeanObjectProperty

我正在努力理解在为通用类型 T 构建 JavaBeanObjectProperty 时我需要做什么才能不丢失类型信息。一个有趣的细节是我没有从 IntelliJ 收到针对 ReadOnlyJavaBeanObjectProperty 的警告。

public class FooWrapper<T> {
    /**
     * Decorates a Foo instance with javafx stuff
     */
    private final Foo foo;

    private final JavaBeanObjectProperty<T> value;
    private final ReadOnlyJavaBeanObjectProperty<T> type;

    public ParameterWrapper(Foo toWrap) {
        this.foo = toWrap;
        try {
            this.value = new JavaBeanObjectPropertyBuilder<T>()
                    .bean(this.foo)
                    .name("value")
                    .build();
            this.type = new ReadOnlyJavaBeanObjectPropertyBuilder<T>()
                    .bean(this.foo)
                    .name("type")
                    .build();
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }
}

我读过 Java unchecked operation cast to generic and Java Generics, how to avoid unchecked assignment warning when using class hierarchy? 并且 none 更聪明。

未经检查的警告不是您的错。通用信息未保留,因为 API 实施不当。有一个 未解决的 问题:JDK-8152399。该问题被标记为 "enhancement",但我认为它是一个错误。

问题是由几乎所有JavaBeanObjectPropertyBuilder return 原始类型的方法引起的。唯一的例外是 build,其中 returns JavaBeanObjectProperty<T>。然而,这并不重要,因为当您调用 build 时,您已经丢失了调用 beanname 的类型信息。不幸的是,这意味着您无法合法地摆脱警告——您只能抑制它。

public class FooWrapper {

  private final Foo delegate;

  private final JavaBeanObjectProperty<SomeType> value;

  @SuppressWarnings("unchecked") // Reason: Bad API
  public FooWrapper(Foo delegate) {
    this.delegate = delegate;
    try {
      value = JavaBeanObjectPropertyBuilder.create()
          .bean(delegate)
          .name("value")
          .build();
    } catch (NoSuchMethodException ex) {
      throw new RuntimeException(ex);
    }
  }

}

这使用 @SuppressWarnings to suppress the unchecked warnings. You can read more about it here。最好将 @SuppressWarnings 应用于尽可能窄的范围,以避免抑制其他有用的警告。


为了比较,请查看 ReadOnlyJavaBeanObjectPropertyBuilder 的方法签名。它们都是 return 通用类型。