Open In App

@SafeVarargs Annotation in Java 9 with Example

Last Updated : 17 Jan, 2020
Improve
Improve
Like Article
Like
Save
Share
Report

@SafeVarargs Annotation: @SafeVarargs annotation is introduced in JDK 7. @SafeVarargs annotation is used to suppress the unsafe operation warnings at the compile time. Unsafe operation warnings come at the compile time whenever in our code we invoked the method which is having varargs i.e. variable number of arguments. The @SafeVarargs annotation can be used with method/constructor and method should be final or static. We can use @SafeVarargs annotation with the methods that cannot be overridden because an overriding method can still perform unsafe operation on their varargs. @SafeVarargs annotation is used to indicate that methods will not cause heap pollution. These methods are considered to be safe.

In JDK 9, JDK developers extended the use of @SafeVarargs annotation, now apart from the final or static method we can use @SafeVarargs annotation with private method also. This is because private methods cannot be overridden.

What is unsafe operation warnings?

Java 5 introduced the concept of Varargs, or a method parameter of variable length, as well as Generics and the unchecked or unsafe operations warning was added this time only. Now the question is why compiler throws a warning when we use the method with varargs or we use Generics? When compiler throws unsafe operation warning then compiler usually asking you to be more explicit about types, in one way or another.

Lets understand the concept with some examples:




// 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);
    }
}


Compile Time Console:

Note: Geeksforgeeks.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

Output:

[OOPS, COLLECTION]

Here we have one method with varargs of type List. But here we did not mention the type of data that List will store. Here compiler will warn you that I am not going to check your code. I am not going to check the values you will add to ArrayList are of any particular type or not. That’s why it will throw unsafe operation warnings at the compile time. Here compiler wants to know the type like




List<String> geeks = new ArrayList<String>();


If we will create ArrayList with type, then the compiler will not throw any warning message at the compile time.

Let’s run the same code again after using the @SafeVarargs annotation.




// 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);
    }
}


Output:

[OOPS, COLLECTION]

Note:Suppose If you want to run the above code in JDK 7 or JDK 8 then you will get a compilation error because these enhancements are done in Java 9, prior to java 9 – private methods are not allowed to be marked with this annotation.




// 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);
    }
}


Compile Time Console:

Note: Geeks.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

Output:

[OOPS, COLLECTIONS, EXCEPTION-HANDLING]

Let’s run the same code again after using the @SafeVarargs annotation.




// 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);
    }
}


Output:

[OOPS, COLLECTIONS, EXCEPTION-HANDLING]


Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads