java - 使用 "raw types"作为静态字段/返回类型时如何避免泛型警告?

标签 java generics unchecked raw-types

这基本上是对 question 的后续从昨天。我试图实现“最通用的方式”(我能想到的)以构建“真正的”不可修改的集合。下面的代码工作正常;但它需要抑制警告(“rawtypes”和“unchecked”)。

我尝试了各种方法来避免这些警告;但根本找不到替代方案。所以,我的问题是:是否有一种干净的方法来避免我抑制的警告?

(我看到了另一个 question ;但我不能 100% 确定它是否真的适用于我的代码;因为我不确定我是否可以在不使用原始类型的情况下写下“Generator”接口(interface))。

private interface Generator<T> {
    T generateNewInstance();
}

@SuppressWarnings("rawtypes")
private final static Generator ListGenerator = new Generator<List>() {
    @Override
    public List generateNewInstance() {
        return new ArrayList();
    }
};

public static <T> List<T> unmodifiableListBasedOnCloneOf(List<T> elements) {
    @SuppressWarnings("unchecked")
    List<T> newInstance = makeNewInstanceOf(elements.getClass(), ListGenerator);
    newInstance.addAll(elements);
    return Collections.unmodifiableList(newInstance);
}

private static <T> T makeNewInstanceOf(Class<T> incomingClass, Generator<T> fallbackGenerator) {
    try {
        return (T) incomingClass.newInstance();
    } catch (IllegalAccessException | InstantiationException e) {
        return fallbackGenerator.generateNewInstance();
    }
}

最佳答案

如果您复制 List<T>进入一个新的ArrayList<T> , 并将该引用内联传递给 Collections.unmodifiableList ,除了不可修改的装饰器之外,没有其他任何东西可以访问副本来修改它:

    List<String> original = new ArrayList<>(Arrays.asList("Hello", "World"));

    // This simply decorates original, so updates to original are
    // reflected in this list.
    List<String> unmodifiableDecorator = Collections.unmodifiableList(original);

    // The reference to the new ArrayList is scoped to the call to
    // Collections.unmodifiableList, so nothing else can have a
    // reference to it.
    List<String> unmodifiableCopy =
        Collections.unmodifiableList(new ArrayList<>(original));

    System.out.println("Before clear:");
    System.out.println(original);
    System.out.println(unmodifiableDecorator);
    System.out.println(unmodifiableCopy);

    original.clear();

    System.out.println("After clear:");
    System.out.println(original);
    System.out.println(unmodifiableDecorator);
    System.out.println(unmodifiableCopy);

输出:

Before clear:
[Hello, World]
[Hello, World]
[Hello, World]
After clear:
[]
[]
[Hello, World]

所以 unmodifiableCopy没有被修改,也不能被修改,除非你能以某种方式说服 unmodifiableList向您提供委托(delegate)引用。

因为您不能修改它,所以您不需要使副本与输入列表具有相同的具体列表类型。只需将其设为 ArrayList ,因为它几乎具有 List 可以实现的最佳读取性能实现。

所以你的方法,没有警告或额外的类,可以是:

public static <T> List<T> unmodifiableListBasedOnCloneOf(List<T> elements) {
  return Collections.unmodifiableList(new ArrayList<>(elements));
}

关于java - 使用 "raw types"作为静态字段/返回类型时如何避免泛型警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36768707/

相关文章:

c# - 为什么将 int.MinValue 除以 -1 在未经检查的上下文中抛出 OverflowException?

java - Android 中特定边邻接矩阵中的 Dijkstra 算法

java - JVM 内部如何解释 010 或 0110 数字

c# - 如何返回具有泛型类型的类实例作为具有泛型类型的接口(interface)?

Java:通用类型转换,我该如何解决这个问题,这样我就不会抑制未经检查的警告

java - Android:使用未经检查或不安全的操作

Java 泛型 : array creation, 类型转换和未经检查的警告

java - 关于 Struts-Default 和 json-default 扩展

java - 使用多个线程处理单个 HTTP 请求

swift - 将 [AnyObject] 转换为可能是也可能不是集合类型的泛型