What is a mutable parameter
- Variable-length parameters are provided in Java 5, allowing for the passing of indefinite lengths of parameters when invoking a method. The variable-length parameter is a syntactic sugar in Java and is essentially an array-based implementation
void foo(String... args);void foo(String[] args);
Method signature
([ljava/lang/string;) V//public void foo (string[] args)
Defining methods
When defining a method, adding a three point "..." after the last parameter means that the parameter can accept more than one argument value, and multiple values are passed in as an array. The above definitions have several important points to note:
A mutable parameter can only be used as the last parameter of a function, but it may or may not have any other parameters before it
Since a mutable parameter must be the last parameter, a function can have at most one variable parameter
The variable parameters of Java are transformed into an array by the compiler
The variable-length parameter is in the form of an array in the method signature after it is compiled into a byte code. The signatures of the two methods are consistent and cannot be overloaded as methods. If it occurs at the same time, it cannot be compiled. mutable parameters can be compatible with arrays, but vice versa
public void foo(String...varargs){}foo("arg1", "arg2", "arg3");//上述过程和下面的调用是等价的foo(new String[]{"arg1", "arg2", "arg3"});
- A "generic" mechanism has been added to J2SE 1.5 to parameterize a type under certain conditions. For example, when writing a class, the type of the formal parameter of a method is represented by an identifier (such as T), and when the identifier exactly represents what type it is, it is specified when the instance of the class is generated. This mechanism can be used to provide more full code reuse and stricter compile-time type checking. However, a generic mechanism cannot be used with a variable number of parameters. If the type of a formal parameter that matches an indeterminate argument is represented by an identifier, the compiler will give a "Generic array creation" error
Publicclass Varargs { public static void Test (string ... args) {for (string Arg:args) {//as Number Group with foreach traversal System.out.println (ARG); }} //compile error //the variable argument type Object of the method must be the last parameter //public vo ID Error1 (String ... args, Object o) {} //public void Error2 (String ... args, Integer ... i) {} //compile error
//duplicate method Test (String ...) in type Varargs
//public void Test (string[] args) {}
Invocation of a mutable parameter method
- The variable parameter method can be called to give 0 to any number of arguments, and the compiler converts the mutable parameter into an array. You can also pass an array directly, as shown below
Publicclass varargs {public static void test (String ... args) {for (String Arg:args) {System.out.println (ARG);}} public static void main (string[] args) {test (); "a", "B"); new string[] { "a", "B", "C"}); //pass the array directly}}
Method overload first matches fixed parameters
- When calling an overloaded method, if the call can match both the overloaded method of the fixed parameter and the overloaded method of the variable-length parameter, the method of selecting the fixed parameter
Publicclass varargs {public static void Test (String ... args) {System.out.println ( "version 1");} public static void test (string arg1, String arg2) {System.out.println (" version 2 ");} public static void Main (string[] args) {test ( "a", //version 1}}
Match multiple variable parameters
- When an overloaded method is called, the compilation error occurs if the call can match the overloaded methods of two variable-length arguments
public class Varargs { public static void Test (String ... args) {System.out.println ("ve Rsion 1 "); the public static void Test (string arg1, String ... arg2) {System.out.println ("version 2");} public static void main (string[] args) {test ("a","B"); Compile Error}}
Method overrides to avoid method overloads with variable-length parameters
- Even though the compiler can determine the specific invocation method by prioritizing the fixed parameters, it is still easy to fall into the trap when reading the code. Method overloads to carefully consider variable-length parameters
Do not let null values and Null values threaten the variable length method
PublicClassClient {public void methodA (String str, Integer ... is) {} public void MethodA (String str,string ... strs) {} public static void main (string[] args) {Client client = new Client (); Client.methoda ( "China", 0); Client.methoda ( //compile error Client.methoda ( "China", null); //compile Error}}
public static void main(String[] args) { Client client = new Client(); String[] strs = null; client.methodA("China",strs); }
- Let the compiler know that this null value is of type string, the compilation will pass smoothly, and the error can be reduced.
The way to overwrite the variable length is to obey the rules.
Package com;PublicClassVarArgsTest2 {/** *@param args */Publicstatic void main (String[] args) { Span class= "hljs-comment" >//TODO auto-generated Method stub //up transformation Base base = new Sub (); Base.print ( "hello"); //does not transition sub Sub = new Sub (); Sub.print ( "hello"); //compile Error}} //base class class Base {void print (String ... args) { System.out.println ( "Base......test");}} //subclass, Override parent class method class Sub extends Base { @Override void print (string[] args) {System.out.println (
The first one can be compiled through, which is why? In fact, the base object has been transformed into a class object sub, and the formal parameter list is determined by the parent class, and of course it does. To see what the subclass calls directly, the compiler sees the subclass overwrite the Print method of the parent class, so the print method redefined by the subclass is definitely used, although the argument list does not match and does not go to the parent class to match, because it is not found, so there is a type mismatch error
This is a special case, the override of the method parameter list can be different from the parent class, which violates the overwrite definition, and will cause a baffling error
Here, summarize the conditions that must be met for the overwrite:
Overwrite method does not narrow access rights
The parameter list must be the same as the Overwrite method (including the display form)
The return type must be the same as the Overwrite method or its subclasses
The Overwrite method cannot throw a new exception, or an exception that is outside the scope of the parent class, but can throw fewer, more limited exceptions, or not throw an exception
Problems that may occur using the Object ... As the variable length parameter
PublicvoidFoo (Object ... args) {System.out.println (args.length);} FooNew string[]{"Arg1","Arg2","Arg3"});3foo (100,new string[]{ "Arg1", "Arg1"}); Span class= "Hljs-comment" >//2foo (new integer[]{1, 2, 3}); //3foo (100, new Integer[]{1, 2, 3}); //2foo (1, 2, 3); //3foo (new int[]{1, 2, 3}); //1
- Int[] cannot be transformed into object[] and is thus treated as a simple array object; Integer[] can be transformed to object[] and can be used as an array of objects
Considerations for Reflection Method invocation
PublicClassTest {PublicStaticvoid foo (String ... varargs) {System.out.println (args.length);} public static void main (string[] args) {string[] VarArgs = new string[]{ "Arg1", "arg2"}; try{method = Test.class.getMethod ( "foo", string[]. Class); Method.invoke (null, VarArgs); Method.invoke (null, (Object[] ) VarArgs); Method.invoke (null, (Object) VarArgs), Method.invoke (null, Span class= "Hljs-keyword" >new Object[]{varargs}); } catch (Exception e) {e.printstacktrace ();}}
Of the above four calls, the first two throws the Java.lang.IllegalArgumentException:wrong number of arguments exception at run time, and the latter two are normally called
Reflection is obtained at run time and, at run time, variable-length parameters and arrays are consistent, so the method signature is:
//方法签名([Ljava/lang/String;)V // public void foo(String[] varargs)
- Take a look at the method declaration of the Methods object:
Object invoke(Object obj, Object... args)
- Although args is a variable-length parameter, the length of args is limited by the length of the argument list of the real method represented by the method object, and from the runtime signature ([ljava/lang/string;) V actually has only one formal parameter, i.e. string[] varargs, Thus the argument length of the variable parameter args in Invoke (Object obj, object ... args) can only be 1
//Object invoke(Object obj, Object... args)//String[] varArgs = new String[]{"arg1", "arg2"};method.invoke(null, varArgs); //varArgs长度为2,错误method.invoke(null, (Object[])varArgs); //将String[]转换为Object[],长度为2的,错误method.invoke(null, (Object)varArgs);//将整个String[] 转为Object,长度为1,符合method.invoke(null, new Object[]{varArgs});//Object[]长度为1,正确。上一个和这个是等价的
When do I use variable length parameters?
- There is a problem with the use of variable length parameters on Stack Overflow. To put it simply,
Variable-length parameters can be used when unsure how many objects the method needs to handle, making the method call simpler, without having to manually create the array new t[]{...}
Java mutable parameters