Java in-depth understanding of Java variable-length parameters

Source: Internet
Author: User
Tags string format

by J2SE 1.4, it was not possible to define a variable number of arguments in a Java program-because Java requires both the number and type of arguments (Arguments) and formal parameters (Parameters) to match each other, and the number of formal parameters is fixed when the method is defined. Although it is possible to provide a version with a different number of parameters for the same method by overloading the mechanism, this still does not achieve the purpose of arbitrarily changing the number of arguments.

However, the semantics of some methods require that they be able to accept a variable number of arguments-such as the well-known main method, which requires that all command-line arguments be accepted as arguments, and that the number of command-line arguments cannot be determined at all beforehand.

Traditionally, the use of an array to wrap the arguments to be passed is generally used to cope with this problem.

1. Wrap an argument with an array

The "Wrap arguments with an array" approach can be divided into three steps: First, define an array-type parameter for this method, and then, when called, generate an array that contains all the arguments to pass, and finally, pass the array as an argument in the past.

This approach can effectively achieve the "let the method can accept the variable number of parameters" purpose, but the invocation of the form is not simple enough.

The meaning of Varargs is provided in J2SE 1.5.

Generally speaking, "Varargs" is the meaning of "variable number of arguments". It is sometimes referred to simply as "variable arguments", but because it does not indicate what is mutable, the meaning is somewhat blurred.

2. How to define the variable number of arguments

Simply add three consecutive "." Between "type" and "parameter name" of a formal parameter. (That is, "...", an ellipsis in an English sentence), it can be matched to an indeterminate argument. A method with such a parameter is a variable number of arguments.

Listing 1: A method with a variable number of arguments

private static int sumup (int ... values) {
}

Note that only the last formal parameter can be defined as "can and does not have an argument to match". Therefore, there can be only one such parameter in a method. Also, if the method has other parameters, put them in the front position.

The compiler converts the last parameter into an array parameter behind the box and makes a tick in the compiled class file, indicating that this is a variable number of arguments.

Listing 2: Secret form of methods with variable number of arguments

private static int SumUp (int[] values) {
}

Because of this transformation, it is no longer possible to define a method that is consistent with the converted method signature for this class.

Listing 3: A combination that causes compilation errors

private static int sumup (int ... values) {
}
private static int SumUp (int[] values) {
}

3. How to invoke a variable number of arguments

You can call a method with a variable number of arguments, as long as you write the arguments you want to pass to a corresponding location. No additional steps are required.

Listing 4: A number of arguments can be passed

SumUp (1, 3, 5, 7);

Secretly, the compiler translates this invocation process into the form of "array wrap arguments":

Listing 5: Secretly appearing array creation

SumUp (new Int[]{1, 2, 3, 4});

Also, there are 0 of "unsure", so the call is reasonable:

Listing 6:0 Arguments can also be passed

SumUp();

This method of invocation is the result of the compiler's secret conversion, which is equivalent to this:

Listing 7:0 arguments corresponding to an empty array

SumUp (new int[]{});

Note that passing in the past is an empty array, not NULL. This can be done in a uniform form, without having to detect exactly which case it belongs to.

4. Handle a variable number of arguments

The method of dealing with a variable number of arguments is basically the same as the method for working with array arguments. All arguments are saved to an array with the same name as the parameter. According to the actual needs, the elements in this array read out, to be steamed to boil, you can be arbitrary.

Listing 8: Handling the Received arguments

private static int SumUp (int ... values) {
int sum = 0;
for (int i = 0; i < values. length; i++) {
sum + = values[i];
}
return sum;
}

5. Forwarding a variable number of arguments

Sometimes, after you accept a set of variable arguments, you pass them to another method with a variable number of arguments. Because there is no way to know the number of accepted sets of arguments in the code, it is not feasible to "write them down to where they appear". However, this does not mean that this is an unfinished task because there is another way to invoke a variable number of arguments.

In the eyes of the compiler for J2SE 1.5, the variable number of arguments is a special case of the method with the last array parameter. Therefore, the entire set of arguments to be passed is placed in an array beforehand, and the array is passed as the last argument to a variable number of arguments, without causing any errors. With this feature, the forwarding can be completed smoothly.

Listing 9: Forwarding the Received arguments

public class Printfsample {
public static void Main (string[] args) {
PrintOut ("Pi:%f e:%f\n", Math.PI, MATH.E);
}
private static void PrintOut (String format, Object ... args) {
System.out.printf (format, args);
}
}

6. Is it an array? Not an array?

Although secretly, the compiler converts a parameter that can match an indeterminate argument to an array parameter, and it can also be passed to a variable number of arguments by using a list of arguments, but this does not mean that there is no difference between a parameter that can match an indeterminate argument and an array parameter.

One obvious difference is that if you call a method that is the array parameter in the form of a variable number of arguments to invoke, only a compilation error of "cannot be applied" is caused.

Listing 10: A compile error for "cannot be applied to"

private static void Testoverloading (int[] i) {
System.out.println ("A");
}
public static void Main (string[] args) {
Testoverloading (1, 2, 3);//Compilation error
}

For this reason, you cannot directly use this concise invocation method when calling a method that only supports the use of an array to wrap arguments (for example, those left behind in a third-party class library that is not specifically designed for J2SE 1.5).

If you cannot modify the original class and add a variable number of arguments to the method you want to invoke, and you want to use this concise invocation, you can introduce a local extension with the introduction of an additional function (introduce Foreign method) and Extension) "to approximate the purpose of the reconstruction technique.

7. When a variable number of arguments encounters a generic

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.

Listing 11: When VarargsMeet the generic type

private static void Testvarargs (T... args) {//Compile error
}

This behavior is caused by an intrinsic constraint on the generic mechanism in J2SE 1.5--You cannot create an instance of this type with the type represented by the identifier. There is basically no good solution to this problem until there is a Java version that supports this constraint.

However, the traditional "wrap with arrays" approach is not constrained by this constraint.

Listing 12: Workarounds that can be compiled

private static void Testvarargs (T[] args) {
for (int i = 0; i < args.length; i++) {
System.out.println (Args[i]);
}
}

8. Selection problems in overloading

Java supports the "overloaded" mechanism, which allows for a number of different methods that have only formal parameter lists in the same class. The compiler then chooses which method to execute based on the arguments that are called.

The traditional choice is basically based on the principle of "special preference". The special degree of a method depends on the number of conditions that need to be met in order for it to run smoothly, and the more specific the requirement is.

After introducing the introduction of the Varargs mechanism, it is possible to have two versions that can match, and also indistinguishable in other respects, just a case where the number of arguments is fixed and a variable number of arguments is present.

When this happens, the decision rule is "a version with a fixed number of arguments takes precedence over a variable number of arguments."

Listing 13: The fixed number of arguments is the preferred version

If, in the compiler's view, more than one method has the same priority, it will fall into a state where it is impossible to make a selection of which method to invoke. At this time, it will produce a "reference to be called method name is ambiguous" compile error, and patiently wait for some changes, enough to exempt it from the confusion of the arrival of the source code.

After the introduction of the Varargs mechanism, this could lead to confusion and a number of additional cases. For example, there may be two versions that can match, and in other respects, they are conflicting occurrences with variable number of arguments.

public class Overloadingsamplea {
public static void Main (string[] args) {
Testoverloading (1);//Print out a
Testoverloading (1, 2);//Print out B
Testoverloading (1, 2, 3);//Print out C
}
private static void testoverloading (int i) {
System.out.println ("A");
}
private static void testoverloading (int i, int j) {
System.out.println ("B");
}
private static void testoverloading (int i, int ... more) {
System.out.println ("C");
}
}
If, in the compiler's view, more than one method has the same priority, it will fall into a state where it is impossible to make a selection of which method to invoke. At this time, it will produce a "reference to be called method name is ambiguous" compile error, and patiently wait for some changes, enough to exempt it from the confusion of the arrival of the source code.

After the introduction of the varargs mechanism, this could lead to confusion and a number of additional cases. For example, there may be two versions that can match, and in other respects, they are conflicting occurrences with variable number of arguments.

Listing 14: No, it's embarrassing. Compiler

public class Overloadingsampleb {
public static void Main (string[] args) {
Testoverloading (1, 2, 3);//Compilation error
}
private static void Testoverloading (Object ... args) {
}
private static void Testoverloading (object o, Object ... args) {
}
}

In addition, because there is a "autoboxing/auto-unboxing" mechanism in J2SE 1.5, it is possible that two versions can be matched, and the number of arguments is variable, and the other is exactly the same, except that an acceptable argument is a basic type. Another acceptable argument is the collision of the parcel class.

New Issues with List 15:autoboxing/auto-unboxing

public class Overloadingsamplec {
public static void Main (string[] args) {
/* Compilation Error */
Testoverloading (1, 2);
/* or compile Error */
Testoverloading (New Integer (1), new Integer (2));
}
private static void testoverloading (int ... args) {
}
private static void Testoverloading (Integer ... args) {
}
}

9. Summarize

Compared with the "wrap with arrays" approach, the method of changing the number of real arguments is simpler and more clear when the arguments are passed on the call. However, this mechanism also has its own limitations, not a perfect solution.

Source connection: Learn more about Java variable-length parameters

Java in-depth understanding of Java variable-length parameters

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.