![](/img/trans.png)
[英]Java Generics: how handle raw type member variable and avoid warnings?
[英]How to avoid generics warnings when using “raw types” as static field / return type?
從昨天開始,這基本上是對這個問題的追隨。 我試圖實現“最通用的方式”(我能想到)以構建“真正”的不可修改集合。 下面的代碼工作正常; 但它需要禁止顯示警告(“原始類型”和“未選中”)。
我嘗試了各種方法來避免這些警告。 但根本找不到其他選擇。 因此,我的問題是:是否有一種干凈的方法來避免我壓制的警告?
(我看到了另一個問題 ;但是我不確定100%是否確實適用於我的代碼;因為我不確定是否可以在不使用原始類型的情況下寫下“ Generator”接口)。
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]
因此,除非您可以以某種方式說服unmodifiableList
向您提供委托引用,否則unmodifiableCopy
不會被修改,也無法被修改。
由於您無法修改它,因此無需使副本與輸入列表具有相同的具體列表類型。 只需將其設置為ArrayList
,因為它具有使用List
實現可以實現的最佳讀取性能。
因此,沒有警告或額外類的方法可以是:
public static <T> List<T> unmodifiableListBasedOnCloneOf(List<T> elements) {
return Collections.unmodifiableList(new ArrayList<>(elements));
}
並非總是可以避免使用@SuppressWarnings注釋。 我嘗試將其范圍限制為局部變量。
我想出了這個:
private interface Generator<T> {
T generateNewInstance();
}
private static class ListGenerator<T> implements Generator<List<T>> {
@Override
public List<T> generateNewInstance() {
return new ArrayList<>();
}
};
public static <T> List<T> unmodifiableListBasedOnCloneOf(List<T> elements) {
@SuppressWarnings("unchecked")
Class<List<T>> clazz = (Class<List<T>>)elements.getClass();
List<T> newInstance = makeNewInstanceOf(clazz , new ListGenerator<T>());
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();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.