作者:zpy7005434 | 来源:互联网 | 2024-10-30 19:13
@ Java 9 中的 SafeVarargs 注释,示例原文:https://www . geesforgeks . org/
@ Java 9 中的 SafeVarargs 注释,示例
原文:https://www . geesforgeks . org/safevarags-annotation-in-Java-9-with-example/
@SafeVarargs 注释 : @SafeVarargs 注释引入 JDK 7。@SafeVarargs 注释用于在编译时抑制不安全的操作警告。每当我们在代码中调用具有可变参数的方法时,不安全操作警告就会在编译时出现。@SafeVarargs 注释可以与方法/构造函数一起使用,并且方法应该是最终的或静态的。我们可以对不能被重写的方法使用@SafeVarargs 注释,因为重写方法仍然可以对它们的 Varargs 执行不安全的操作。@ SafeVarargs 注释用于指示方法不会导致堆污染。这些方法被认为是安全的。
在 JDK 9 中,JDK 开发人员扩展了@ safevarags 注释的使用,现在除了 final 或 static 方法之外,我们还可以在 private 方法中使用@ safevarags 注释。这是因为不能重写私有方法。
什么是不安全操作警告?
Java 5 引入了 Varargs 的概念,或者说是一个可变长度的方法参数,以及 Generics ,这次只增加了未检查或者不安全操作的警告。现在的问题是,为什么当我们将方法与 varargs 一起使用或使用泛型时,编译器会抛出警告?当编译器抛出不安全操作警告时,编译器通常会以某种方式要求您更明确地说明类型。
我们用一些例子来理解这个概念:
// 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<String> topic : topics) {
System.out.println(topic);
}
}
public static void main(String[] args)
{
Geeksforgeeks obj = new Geeksforgeeks();
List<String> list = new ArrayList<String>();
list.add("OOPS");
list.add("COLLECTION");
obj.print(list);
}
}
编译时控制台:
Note: Geeksforgeeks.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
输出:
这里我们有一个方法,它的 varargs 类型为 List。但是这里我们没有提到 List 将存储的数据类型。这里编译器会警告你,我不会检查你的代码。我不会检查您将添加到数组列表中的值是否属于任何特定类型。这就是为什么它会在编译时抛出不安全的操作警告。这里编译器想知道类型
List<String> geeks = new ArrayList<String>();
如果我们用类型创建数组列表,那么编译器在编译时不会抛出任何警告消息。
让我们在使用@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<String> topic : topics) {
System.out.println(topic);
}
}
public static void main(String[] args)
{
Geeksforgeeks obj = new Geeksforgeeks();
List<String> list = new ArrayList<String>();
list.add("OOPS");
list.add("COLLECTION");
obj.print(list);
}
}
输出:
注意:假设如果你想在 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<T> {
private List<T> 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<T> {
private List<T> 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]