【发布时间】:2023-03-31 17:42:01
【问题描述】:
这基本上是昨天question 的后续。我试图实现“最通用的方式”(我能想到的)以构建“真正的”不可修改的集合。下面的代码工作正常;但它需要抑制警告(“rawtypes”和“unchecked”)。
我尝试了各种方法来避免这些警告;但根本找不到替代方案。所以,我的问题是:有没有一种干净的方法来避免我正在压制的警告?
(我看到了另一个question;但我不确定它是否真的适用于我的代码;因为我不确定是否可以在不使用原始类型的情况下写下“生成器”接口)。
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();
}
}
【问题讨论】:
-
我真的不明白您在这里要做什么:如果列表包含在
unmodifiableList中,那么底层列表的类型有什么关系?为什么Collections.unmodifiableList(new ArrayList<>(elements))不够用? -
请阅读我的另一个问题。关键是:它不是。该 Collections 方法仅将 decorator 添加到现有列表中。如果您通过未修饰的界面访问该“初始列表”,则可以更改该列表;然后你所谓的不可修改的列表在封面下发生了变化。
-
Collections.unmodifiableCollection(new ArrayList<>(elements))不是elements的视图:它将elements复制到一个新列表中(就像您在此处所做的那样),并且该新列表的引用无法访问unmodifiableCollection以外的任何东西。 -
我强烈建议您使用现有的解决方案。例如,Guava 有一些很棒的不可变集合,它们不仅比这些基于装饰器的方法性能更高,而且还可以避免不必要的复制。 Guava 的不可变集合的主要警告是它们不支持空值。
-
正如我在这个问题中提到的另一个问题中所写的那样:番石榴不是一种选择。
标签: java generics unchecked raw-types