Java 如何在使用时避免泛型警告;“原始类型”;是否为静态字段/返回类型?
这基本上是从昨天开始的后续行动。我试图实现“最通用的方式”(我能想到的),以构建“真正的”不可修改的集合。下面的代码工作正常;但它需要抑制警告(“rawtypes”和“unchecked”) 我尝试了各种方法来避免这些警告;但根本找不到替代方案。所以,我的问题是:有没有一种干净的方法来避免我压制的警告 (我看到了另一个;但我不能100%确定它是否真的适用于我的代码;因为我不确定我是否可以在不使用原始类型的情况下写下“Generator”接口)Java 如何在使用时避免泛型警告;“原始类型”;是否为静态字段/返回类型?,java,generics,unchecked,raw-types,Java,Generics,Unchecked,Raw Types,这基本上是从昨天开始的后续行动。我试图实现“最通用的方式”(我能想到的),以构建“真正的”不可修改的集合。下面的代码工作正常;但它需要抑制警告(“rawtypes”和“unchecked”) 我尝试了各种方法来避免这些警告;但根本找不到替代方案。所以,我的问题是:有没有一种干净的方法来避免我压制的警告 (我看到了另一个;但我不能100%确定它是否真的适用于我的代码;因为我不确定我是否可以在不使用原始类型的情况下写下“Generator”接口) 专用接口生成器{ T生成性(); } @抑制警告(“
专用接口生成器{
T生成性();
}
@抑制警告(“原始类型”)
专用最终静态生成器ListGenerator=新生成器(){
@凌驾
公共列表generateNewInstance(){
返回新的ArrayList();
}
};
公共静态列表不可修改ListBasedOnCloneof(列表元素){
@抑制警告(“未选中”)
List newInstance=makeNewInstanceOf(elements.getClass(),ListGenerator);
newInstance.addAll(元素);
返回集合。不可修改列表(newInstance);
}
私有静态T makeNewInstanceOf(类incomingClass、生成器fallbackGenerator){
试一试{
返回(T)incomingClass.newInstance();
}catch(IllegalAccessException |实例化exception e){
返回fallbackGenerator.generateNewInstance();
}
}
不可能总是避免@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();
}
}
专用接口生成器{
T生成性();
}
私有静态类ListGenerator实现了{
@凌驾
公共列表generateNewInstance(){
返回新的ArrayList();
}
};
公共静态列表不可修改ListBasedOnCloneof(列表元素){
@抑制警告(“未选中”)
Class clazz=(Class)elements.getClass();
List newInstance=makeNewInstanceOf(clazz,newlistgenerator());
newInstance.addAll(元素);
返回集合。不可修改列表(newInstance);
}
私有静态T makeNewInstanceOf(类incomingClass、生成器fallbackGenerator){
试一试{
返回(T)incomingClass.newInstance();
}catch(IllegalAccessException |实例化exception e){
返回fallbackGenerator.generateNewInstance();
}
}
不可能总是避免@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();
}
}
专用接口生成器{
T生成性();
}
私有静态类ListGenerator实现了{
@凌驾
公共列表generateNewInstance(){
返回新的ArrayList();
}
};
公共静态列表不可修改ListBasedOnCloneof(列表元素){
@抑制警告(“未选中”)
Class clazz=(Class)elements.getClass();
List newInstance=makeNewInstanceOf(clazz,newlistgenerator());
newInstance.addAll(元素);
返回集合。不可修改列表(newInstance);
}
私有静态T makeNewInstanceOf(类incomingClass、生成器fallbackGenerator){
试一试{
返回(T)incomingClass.newInstance();
}catch(IllegalAccessException |实例化exception e){
返回fallbackGenerator.generateNewInstance();
}
}
如果将列表
复制到一个新的数组列表
,并将该引用内联传递到集合。不可修改列表
,则除了不可修改的装饰器之外,没有其他任何东西可以访问该副本来修改它:
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);
因此,unmodifiableCopy
不会被修改,也不能被修改,除非您能够以某种方式说服unmodifiableList
将代理引用提供给您
由于无法修改它,因此不需要将副本设置为与输入列表相同的具体列表类型。只需将其设置为ArrayList
,因为它具有几乎可以通过列表实现的最佳读取性能
因此,在没有警告或额外类的情况下,您的方法可以是:
public static <T> List<T> unmodifiableListBasedOnCloneOf(List<T> elements) {
return Collections.unmodifiableList(new ArrayList<>(elements));
}
公共静态列表不可修改ListBasedOnCloneof(列表元素){
返回集合。不可修改列表(新的ArrayList(元素));
}
如果将列表
复制到一个新的数组列表
,并将该引用内联传递到集合。不可修改列表
,则除了不可修改的装饰器之外,没有其他任何东西可以访问该副本来修改它:
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);
因此,unmodifiableCopy
不会被修改,也不能被修改,除非您能够以某种方式说服unmodifiableList
将代理引用提供给您
由于无法修改它,因此不需要将副本设置为与输入列表相同的具体列表类型。只需将其设置为ArrayList
,因为它具有几乎可以通过列表实现的最佳读取性能
因此,在没有警告或额外类的情况下,您的方法可以是:
public static <T> List<T> unmodifiableListBasedOnCloneOf(List<T> elements) {
return Collections.unmodifiableList(new ArrayList<>(elements));
}
公共静态列表不可修改ListBasedOnCloneof(列表元素){
返回集合。不可修改列表(新的ArrayList(元素));
}
我明白了。保存其中一个警告;以单个“new”语句的微妙代价(这可能是过早的优化;但我特意提出了一个解决方案,试图在没有引发异常的“良好”情况下最小化发生的“活动”。incomingClass.newInstance()
可以绕过编译器对已检查异常的支持。如果调用incomingClass.getConstructor().newInstance()
它将迫使您捕获InvocationTargetException
,它将包装构造函数中抛出的异常,允许您处理它们或使用您认为合适的fallbackGenerator
。我明白了。保存其中一个警告;以罪恶的微妙代价