Java 9 中的@SafeVarargs 注释与示例
@SafeVarargs 注解:@SafeVarargs 注解是在JDK 7 中引入的。@SafeVarargs 注解用于抑制编译时的不安全操作警告。每当在我们的代码中调用具有可变参数(即可变数量的参数)的方法时,就会在编译时出现不安全操作警告。 @SafeVarargs 注释可以与方法/构造函数一起使用,方法应该是最终的或静态的。我们可以将@SafeVarargs 注释与无法覆盖的方法一起使用,因为覆盖方法仍然可以对其可变参数执行不安全的操作。 @SafeVarargs 注解用于表示方法不会造成堆污染。这些方法被认为是安全的。
在 JDK 9 中,JDK 开发人员扩展了 @SafeVarargs 注解的使用,现在除了 final 或 static 方法之外,我们还可以将 @SafeVarargs 注解与私有方法一起使用。这是因为私有方法不能被覆盖。
什么是不安全操作警告?
Java 5 引入了 Varargs 的概念,即可变长度的方法参数,以及 Generics,并且这次仅添加了未检查或不安全操作警告。现在的问题是,当我们使用带有可变参数的方法或使用泛型时,为什么编译器会抛出警告?当编译器抛出不安全操作警告时,编译器通常会要求您以一种或另一种方式更明确地说明类型。
让我们通过一些例子来理解这个概念:
// Program to illustrate the unsafe operation warnings
// message with respect to varargs parameter
import java.util.ArrayList;
import java.util.List;
public class Geeksforgeeks {
// print is a method with variable argument
private void print(List... topics)
{
for (List topic : topics) {
System.out.println(topic);
}
}
public static void main(String[] args)
{
Geeksforgeeks obj = new Geeksforgeeks();
List list = new ArrayList();
list.add("OOPS");
list.add("COLLECTION");
obj.print(list);
}
}
编译时控制台:
Note: Geeksforgeeks.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
输出:
[OOPS, COLLECTION]
这里我们有一个 List 类型的可变参数的方法。但是这里我们没有提到 List 将存储的数据类型。这里编译器会警告你我不会检查你的代码。我不会检查您将添加到 ArrayList 的值是否属于任何特定类型。这就是为什么它会在编译时抛出不安全操作警告。这里编译器想知道类型
List geeks = new ArrayList();
如果我们将创建具有类型的 ArrayList,那么编译器将不会在编译时抛出任何警告消息。
让我们在使用 @SafeVarargs 注释后再次运行相同的代码。
// Program to illustrate the
// @SafeVarargs with respect to varargs
import java.util.ArrayList;
import java.util.List;
public class Geeksforgeeks {
// Here we used @SafeVarargs annotation,
// now we will not get any unchecked
// or unsafe operations warning message
// at compile time
@SafeVarargs
private void print(List... topics)
{
for (List topic : topics) {
System.out.println(topic);
}
}
public static void main(String[] args)
{
Geeksforgeeks obj = new Geeksforgeeks();
List list = new ArrayList();
list.add("OOPS");
list.add("COLLECTION");
obj.print(list);
}
}
输出:
[OOPS, COLLECTION]
注意:假设如果您想在 JDK 7 或 JDK 8 中运行上述代码,那么您将收到编译错误,因为这些增强功能是在Java 9 中完成的,在Java 9 之前 - 不允许使用此注释标记私有方法。
// Program to illustrate the unsafe
// operation warnings message
// with respect to Generics
import java.util.ArrayList;
import java.util.List;
public class Geeks {
private List topics = new ArrayList<>();
// Here add() is a method with varargs of type T
// Here T is unknown for
// the compiler at the compile time
// That's why It will throw unsafe
// operation warning message
public final void add(T... toAdd)
{
for (T topic : toAdd) {
topics.add(topic);
}
}
public static void main(String[] args)
{
Geeks geek = new Geeks();
geek.add("OOPS",
"COLLECTIONS",
"EXCEPTION-HANDLING");
System.out.println(geek.topics);
}
}
编译时控制台:
Note: Geeks.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
输出:
[OOPS, COLLECTIONS, EXCEPTION-HANDLING]
让我们在使用 @SafeVarargs 注释后再次运行相同的代码。
// Program to illustrate the
// @SafeVarargs with respect to Generics
import java.util.ArrayList;
import java.util.List;
public class Geeks {
private List topics = new ArrayList<>();
// Here by placing @SafeVarargs annotation
// to add() method, we are ensuring to the
// compiler that our action is safe.
// That's why compiler will not throw
// any warning message at the compile time.
@SafeVarargs
public final void add(T... toAdd)
{
for (T topic : toAdd) {
topics.add(topic);
}
}
public static void main(String[] args)
{
Geeks geek = new Geeks();
geek.add("OOPS",
"COLLECTIONS",
"EXCEPTION-HANDLING");
System.out.println(geek.topics);
}
}
输出:
[OOPS, COLLECTIONS, EXCEPTION-HANDLING]