如何修复 Java 11 泛型类型安全警告

How to fix Java 11 Generics type safety warning

我对不同类型的 Java 对象的异构通用实现有一些要求。我可以看到与未经检查的转换相关的警告。关于以下实现的任何想法,以避免任何运行时异常。请找到下面的示例代码。

class GenericData<T> {
  
  private final Class<T> type;
  private final static Map<Class<?>, GenericData> map = new HashMap<>(); //Warning :: GenericData is a raw type. References to generic type GenericData<T> should be parameterized

  public final static <T> GenericData<T> of(Class<T> type) {
    return map.putIfAbsent(type, new GenericData<T>(type)); // Warning :: Type safety: The expression of type GenericData needs unchecked conversion to conform to GenericData<T>
  }
  
  private GenericData(Class<T> type) {
    this.type = type;
  }
  
  public final T getDataAfterDefaultValueApplied(T Data, T Body) {
    Map<String, Object> defaultMap = getDataMap(Data);
    Map<String, Object> dataMap = getDataMap(Body);
    defaultMap.putAll(dataMap);
    final ObjectMapper mapper = new ObjectMapper();
    return mapper.convertValue(defaultMap, type);
  }

  private Map<String, Object> getDataMap(T data) {
    // Demo implementation, ignore this one
    return (Map<String, Object>) data;
  }
}

对于这种容器,未经检查的操作是不可避免的。但是您应该尽量减少它,并进一步添加运行时检查以确保类型安全:

class GenericData<T> {
    private final Class<T> type;
    private final static Map<Class<?>, GenericData<?>> map = new HashMap<>();

    public final static <T> GenericData<T> of(Class<T> type) {
        return map.putIfAbsent(type, new GenericData<>(type)).checkedCast(type);
    }

    private GenericData(Class<T> type) {
        this.type = type;
    }

    @SuppressWarnings("unchecked")
    private <U> GenericData<U> checkedCast(Class<U> clazz) {
        if(clazz != this.type) throw new ClassCastException(clazz + " != " + this.type);
        return (GenericData<U>)this;
    }

    // ...
}

此处,未经检查的操作仅限于 checkedCast 方法,reader 可以立即识别它已通过显式检查操作变得安全,只有编译器无法识别它。