SafeVarargs Annotation
The @SafeVarargs annotation is used to perform safe operations on variable arguments. A method that accepts variable arguments may cause unsafe execution. To avoid this issue Java provides @SafeVarargs annotation.
This annotation can be applied only to methods that cannot be overridden. These include static methods, final instance methods, but from Java 9, can be applied to private instance methods.
Example: Java 8 Final Method
Let's create an example to use @SafeVarargs to a final method. Here we have a display() method that takes variable arguments.
public class Main {
@SafeVarargs
final void display(List... items) {
for (List item : items) {
System.out.println(item);
}
}
public static void main(String[] args){
Main m = new Main();
List<String> list = new ArrayList<String>();
list.add("Book");
list.add("Scale");
m.display(list);
}
}
[Book, Scale]
Example: Java 8 Static Method
Let's take one more scenario where we are using @SafeVarargs annotation to a static method. Since static methods can not be overridden so the annotation can be applied.
public class Main {
@SafeVarargs
static void display(List... items) {
for (List item : items) {
System.out.println(item);
}
}
public static void main(String[] args){
Main m = new Main();
List<String> list = new ArrayList<String>();
list.add("Book");
list.add("Scale");
m.display(list);
}
}
[Book, Scale]
Example: Java 8
If we use @SafeVarargs annotation with a private method and compile with Java 8 then we get a compile-time error. See the example below.
import java.util.ArrayList;
import java.util.List;
public class Main {
@SafeVarargs
private void display(List... items) {
for (List item : items) {
System.out.println(item);
}
}
public static void main(String[] args){
Main m = new Main();
List<String> list = new ArrayList<String>();
list.add("Book");
list.add("Scale");
m.display(list);
}
}
Main.java:6: error: Invalid SafeVarargs annotation. Instance method display(List...) is not final.
private void display(List... items) {
^
1 error
Example: Java 9
Here, we have a private method that takes variable arguments and compiled using Java 9. This time it works fine and produces the desired result.
import java.util.ArrayList;
import java.util.List;
public class Main {
@SafeVarargs
private void display(List... items) {
for (List item : items) {
System.out.println(item);
}
}
public static void main(String[] args){
Main m = new Main();
List<String> list = new ArrayList<String>();
list.add("Book");
list.add("Scale");
m.display(list);
}
}
Book
Scale
Example: No @SafeVarargs
If we don't use the annotation with the private instance method and execute it using Java 9 then the compiler executes the code but reports a warning. See the example below.
import java.util.ArrayList;
import java.util.List;
public class Main {
// No annotation
private void display(List... items) {
for (List item : items) {
System.out.println(item);
}
}
public static void main(String[] args){
Main m = new Main();
List<String> list = new ArrayList<String>();
list.add("Book");
list.add("Scale");
m.display(list);
}
}
Note: Main.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Book
Scale