Why do I get a compilation warning here (var args method call in Java)

Java

Java Problem Overview


Source:

public class TestVarArgs {
  public void varArgsMethod(Object ... arr) {
     System.out.println(arr.getClass().getName());
     for(Object o : arr) {
       System.out.println(o);
     }
  }

  public static void main(String[] args) {
    TestVarArgs tva = new TestVarArgs();
    tva.varArgsMethod(args);    
  }
}

Compile:

javac TestVarArgs.java 

Error:

TestVarArgs.java:15: warning: non-varargs call of varargs method with inexact argument type for last parameter;
cast to java.lang.Object for a varargs call
cast to java.lang.Object[] for a non-varargs call and to suppress this warning    
tva.varArgsMethod(args);     
^

1 warning

I am using javac 1.6.0_20 and the code o/p indicates that a non var arg call was made anyways.

Java Solutions


Solution 1 - Java

It is because String[] and Object... do not exactly match up.

You have to cast the String[] to either Object[] (if you want to pass the Strings as separate parameters) or Object (if you want just one argument that is an array) first.

 tva.varArgsMethod((Object[])args);    // you probably want that

 tva.varArgsMethod( (Object) args);    // you probably don't want that, but who knows?

Why is this a warning and not an error? Backwards compatibility. Before the introduction of varargs, you had these methods take a Object[] and code compiled against that should still work the same way after the method has been upgraded to use varargs. The JDK standard library is full of cases like that. For example java.util.Arrays.asList(Object[]) has changed to java.util.Arrays.asList(Object...) in Java5 and all the old code that uses it should still compile and work without modifications.

Solution 2 - Java

The argument of type String[] should explicitly be cast to Object[] for the invocation of the varargs method varArgsMethod(Object...) from type TestVarArgs. It could alternatively be cast to Object for a varargs invocation
You can fix it by doing either one of the way If you cast the String[] to Object[] (ref:tva.varArgsMethod((Object[])args); )
OR
change the parameter of method to String[]
(ref:public void varArgsMethod(String ... paramArr))

Solution 3 - Java

Modify the method as

public void varArgsMethod(String ... arr)

Solution 4 - Java

The casts to Object and Object[] did not work out for me, it broke my code, resulting in "Encountered array-valued parameter binding, but was expecting [java.lang.String (n/a)]" and other randomness.

My line that showed the warning (subj) is the following, where filter.getStates() is of type String[]

p.add(root.join(DeviceEntity_.state, JoinType.LEFT).get(ClassifierEntity_.CODE).in(filter.getStates()));

The solution that worked is to use Arrays.asList(filter.getStates()) instead of casting. Good luck!

Solution 5 - Java

One of the elegant ways to get rid off this warning: instead of tva.varArgsMethod(args) call tva.varArgsMethod(Arrays.stream(args).toArray()) explicitly showing that you pass multiple arguments. Another way to get rid off the warning is to use following call:

tva.varArgsMethod(Arrays.asList(args).toArray())

Anyway we have to convert the args to Array.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAnkur AgarwalView Question on Stackoverflow
Solution 1 - JavaThiloView Answer on Stackoverflow
Solution 2 - JavaFreakView Answer on Stackoverflow
Solution 3 - JavaMGPJView Answer on Stackoverflow
Solution 4 - JavaMadis MänniView Answer on Stackoverflow
Solution 5 - JavaAndrushenko AlexanderView Answer on Stackoverflow