Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simplified Varargs Method Invocation in Java 7

In Java 7, you have the option to put a @SafeVarargs annotation to suppress the warning you get when compiling a method with a non-reifiable varargs parameter. Project Coin's proposal stipulates that the annotation should be used when the method ensures that only elements of the same type as the varargs parameter are stored in the varargs array.

What would be an example of a non-safe method?

like image 653
Jeffrey Avatar asked Oct 22 '11 03:10

Jeffrey


People also ask

What is Varargs method in Java?

Varargs is a short name for variable arguments. In Java, an argument of a method can accept arbitrary number of values. This argument that can accept variable number of values is called varargs. The syntax for implementing varargs is as follows: accessModifier methodName(datatype… arg) { // method body }

Which is the correct syntax of varargs in Java?

The varargs uses ellipsis i.e. three dots after the data type. Syntax is as follows: return_type method_name(data_type... variableName){}

How do you handle varargs in Java?

Important Points regarding Varargs Before JDK 5, variable length arguments could be handled in two ways: One was using overloading, other was using array argument. There can be only one variable argument in a method. Variable argument (Varargs) must be the last argument.

Can Varargs be used in abstract method?

So nope, the forwarder definitely isn't getting implemented. Putting the annotation on both bar methods fails to compile: A method with a varargs annotation produces a forwarder method with the same signature (args: Array[String])Unit as an existing method.


1 Answers

For example, foo() is not safe, it may store non-T in the array, causing problem at [2]

<T extends List<?>> void foo(T... args)
{
    List<String>[] array2 = (List<String>[])args;
    array2[0] = a_list_of_string;
}

void test2()
{
    List<Integer>[] args = ...;   // [1]
    foo(args);
    Integer i = args[0].get(0);   // [2]
}

By marking the method with @SafeVarargs, you promise to compiler that you are not doing anything naughty like that.


But how in hell can we get a generic array at [1] to start with? Java doesn't allow generic array creation!

The only sanctioned way of generic array creation is when calling a vararg method

foo( list_int_1, list_int_2 )

then the array isn't accessible to caller, caller can't do [2] anyway, it doesn't matter how foo() messes with the array.

But then you think about it, it is the backdoor to create generic array

@SafeVarargs
static <E> E[] newArray(int length, E... array)
{
    return Arrays.copyOf(array, length);
}

List<String>[] array1 = newArray(10);

and generic array literal

@SafeVarargs
static <E> E[] array(E... array)
{
    return array;
}

List<String>[] array2 = array( list1, list2 );

So we can create generic array after all... Silly Java, trying to prevent us from doing that.

like image 172
irreputable Avatar answered Oct 04 '22 04:10

irreputable