〜JLS§9.6.4.7
与此同时,您有两种选择;忽略警告或重构您的API。
重构您的API实际上可能正是您想要的,因为泛型可变参数方法应该仅用作实际的桥梁,适当的通用实现。与其将其定义为接口的一部分(因此要求所有实现实现它)将其作为静态实用程序方法提供,从而使接口的API更小,同时仍使呼叫者能够灵活地使用可变参数。从Java 8开始,实用方法甚至可以在界面中定义。
@SafeVarargs
public static< T> ; void addAll(CollectorIF< T> collector,T ... values){
collector.addAll(Arrays.asList(values));
}
然后,您的界面应该定义一个 addAll(Iterable< T>值)
方法,它允许实现者完全避免通用可变参数的垃圾世界。
In this code,
package com.example;
interface CollectorIF<T> {
// @SafeVarargs // Error: @SafeVarargs annotation cannot be applied to non-final instance method addAll
void addAll(T... values);
}
class Collector<T> implements CollectorIF<T> {
@SafeVarargs
public final void addAll(T... values) {
}
}
class Component<T> {
public void compute(T value) {
Collector<T> col1 = new Collector<>();
col1.addAll(value); // No warning
CollectorIF<T> col2 = new Collector<>();
col2.addAll(value); // Type safety: A generic array of T is created for a varargs parameter
}
}
the Type safety: A generic array of T is created for a varargs parameter
warning does not occur when using a Collector<T>
reference, due to the @SafeVarargs
annotation.
However, the warning does occur when accessing the method through the CollectorIF<T>
interface. On interface methods, @SafeVarargs
is not valid (which is obvious since the compiler can not perform any checks on the usage of the parameter in the method body).
How can the warning be avoided when accessing the method through an interface?
解决方案
There's no way to avoid this warning, because there's no way to safely define an interface that has a generic varargs method.
Another implementation of CollectiorIF
could misuse the parameter, rendering any caller of CollectorIF.addAll()
vulnerable to strange runtime behavior. You could make a case that interfaces and non-final methods should allow @SafeVarargs
(and require that implementing/overriding methods be similarly annotated), but presently the Java devs made a conscious decision not to support that pattern.
The JLS provides a little more background:
The annotation is not usable where method overriding occurs. Annotation inheritance only works on classes (not methods, interfaces, or constructors), so an @SafeVarargs-style annotation cannot be passed through instance methods in classes or through interfaces.
~JLS §9.6.4.7
In the meantime you have two choices; ignore the warning or refactor your API.
Refactoring your API is actually likely to be exactly what you want, since generic vararg methods should only be used as bridges to the real, properly-generic implementation. Instead of defining it as part of your interface (and therefore requiring all implementations implement it) provide it as a static utility method, thereby making the interface's API smaller while still giving callers the flexibility to use varargs. As of Java 8 the utility method can even be defined in the interface.
@SafeVarargs
public static <T> void addAll(CollectorIF<T> collector, T... values) {
collector.addAll(Arrays.asList(values));
}
Your interface should then define a addAll(Iterable<T> values)
method which lets implementors avoid the crufty world of generic varargs entirely.
这篇关于@SafeVarargs接口方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!