Creating variable parameters in Java1.5 [Varargs]

Source: Internet
Author: User
Tags final new features object object string string format version variable tostring
Create

Method overloading is one of the most distinctive features of Java and other object-oriented languages. While many people may think that Java has the advantage of its type, or the API library it brings, it is also a good thing to match the same method name with a variety of acceptable parameters.

Guitar Guitar = new Guitar ("bourgeois", "Country Boy Deluxe",
Guitarwood.mahogany, guitarwood.adirondack,1.718);
Guitar Guitar = new Guitar ("Martin", "HD-28");
Guitar Guitar = new Guitar ("Collings", "CW-28"
Guitarwood.brazilian_rosewood, guitarwood.adirondack,1.718,
Guitarinlay.no_inlay, Guitarinlay.no_inlay);

This code calls three versions of the constructor of a (fictional) Guitar class, meaning that information can is supplied When it's available,rather than forcing a user to know everything about their guitar in one time (many professionals could N ' t tell you their guitar ' s width at the nut).
Here are the constructors used:
Public Guitar (String builder, string model) {
}
Public Guitar (String builder, string model,
Guitarwood Backsideswood, Guitarwood Topwood,
Float nutwidth) {
}
Public Guitar (String builder, string model,
Guitarwood Backsideswood, Guitarwood Topwood,
Float Nutwidth,
Guitarinlay Fretboardinlay, Guitarinlay topinlay) {
}

This code calls the three-version constructor in the guitar class, meaning that the information is supported when it is visible, rather than forcing every user to learn all about the guitar class every time. Many experts will not tell you their guitar at a critical time. The following are the constructors used:

Public Guitar (String builder, string model) {
}
Public Guitar (String builder, String Model,guitarwood backsideswood, Guitarwood topwood,float nutwidth) {
}
Public Guitar (String builder, String Model,guitarwood backsideswood, Guitarwood topwood,float nutwidth,
Guitarinlay Fretboardinlay, Guitarinlay topinlay) {
}

However, when you want to add unlimited information, things start to become a little less useful. For example, suppose you want to allow additional unspecified attributes to be added to this constructor. Here are some examples of possible calls:

Guitar Guitar = new Guitar ("Collings", "CW-28"
Guitarwood.brazilian_rosewood, guitarwood.adirondack,1.718,
Guitarinlay.no_inlay, Guitarinlay.no_inlay, "enlarged Soundhole", "NO popsicle brace");
Guitar Guitar = new Guitar ("Martin", "hd-28v", "hot-rodded by Dan Lashbrook", "Fossil Ivory Nut", "Fossil Ivory Saddle", "Lo W-profile Bridge pins ");

For these two separate situations, you have to add a constructor to accept two additional strings, and another constructor to accept four additional strings. Attempts to apply these similar versions to constructors that have already been overloaded. In that case, you will end up with a version of 20 or 30 of those stupid constructors!

The reason is the variable parameters we often call. The variable parameter is another feature of Tiger's increase, and it solves the problem here in a rather ingenious way. This chapter describes various aspects of this relatively simple feature. This will enable you to quickly write better, cleaner, more flexible code.

Create a variable-length argument list

Variable parameters allow you to specify a method to accept multiple parameters of the same type, and do not require a predetermined number of parameters (at compile or runtime).

This is an integral part of Tiger. In fact, it is because some of the new features of the Java language are grouped together to show the characteristics of variable parameters.

How do I achieve it?

First of all, you have to get used to writing ellipses (...). )。 These three dots are key to variable parameters and you will often type them. The following is an example of the constructor of the guitar class that uses variable parameters to accept an indeterminate number of strings:

Public Guitar (String builder, string model, string......features);

Parameter string ... features indicates that any number of strings can be accepted. So, all of the following calls are legal.

Guitar Guitar = new Guitar ("Martin", "hd-28v", "hot-rodded by Dan Lashbrook", "Fossil Ivory Nut", "Fossil Ivory Saddle", "Lo W-profile Bridge pins ");
Guitar Guitar = new Guitar ("bourgeois", "OMC," "incredible flamed maple bindings on this one.");
Guitar Guitar = new Guitar ("Collings", "OM-42", "Once owned by Steve Kaufman--one of a Kind");
You could add the same variable-length argument to the other constructors:
Public Guitar (String builder, string model,
Guitarwood Backsideswood, Guitarwood topwood,float nutwidth, String ... features)
Public Guitar (String builder, string model,
Guitarwood Backsideswood, Guitarwood topwood,float nutwidth,
Guitarinlay fretboardinlay,guitarinlay topinlay,string ... features)

Example 5-1 describes a simple class that puts all of these features together, and even uses XX to pass some variable parameters together.

Example 5-1. Using VarArgs in constructors

Package com.oreilly.tiger.ch05;
public class Guitar {
Private String Builder;
Private String model;
private float nutwidth;
Private Guitarwood Backsideswood;
Private Guitarwood Topwood;
Private Guitarinlay Fretboardinlay;
Private Guitarinlay Topinlay;
Private static final float default_nut_width = 1.6875f;
Public Guitar (String builder, string model, String ... features) {
This (builder, model, NULL, NULL, default_nut_width, NULL, NULL, features);
}
Public Guitar (String builder, string model,
Guitarwood Backsideswood, Guitarwood Topwood,
Float Nutwidth, String ... features) {
This (builder, model, Backsideswood, Topwood, nutwidth, NULL, NULL, features);
}
Public Guitar (String builder, string model,
Guitarwood Backsideswood, Guitarwood topwood,float nutwidth,
Guitarinlay fretboardinlay, Guitarinlay topinlay,string ... features) {
This.builder = Builder;
This.model = model;
This.backsideswood = Backsideswood;
This.topwood = Topwood;
This.nutwidth = Nutwidth;
This.fretboardinlay = Fretboardinlay;
This.topinlay = Topinlay;
}
}

What just happened?

When you specify a variable length parameter list, the Java compiler actually reads "Create an array of type < parameter type >". You type:

Public Guitar (String builder, string model, string ... features)

However: The compiler interprets these for:

Public Guitar (String builder, string model, string[] features)

This means that repeating the list of arguments is simple (which will be described in the "repeat variable-length argument list"), which is the same as the other programming goals you need to accomplish.

You can use variable parameters just as you would with arrays.

However, there are also some limitations. First, in each method, you can use only one ellipsis. So, the following writing is not legal:
Public Guitar (String builder, String model,string ... features, float ... stringheights)

In addition, the ellipsis must be used as the last parameter of the method.

What if you don't need to pass any variable parameters?

That's okay, you just need to call the constructor in the old way:

Guitar Guitar = new Guitar ("Martin", "D-18");

Let's take a closer look, although there are no constructors in the program that match the following code:

Public Guitar (String builder, string model)

So what does the code actually deliver? As a special case of variable parameters, not passing things in parameters is a legitimate option. So, when you see string ... features, you should think of it as 0 or more string arguments. This saves you from creating another hassle without the variable parameter builder.

Repeating variable-length parameter class table

All of these variable parameters are good. But in fact, if you don't use them in your approach, they're obviously just eye-catching things or window decorations.

However, you can use variable parameters just as you would use an array, and you will find this usage very simple.

So how do I use variable parameters?

First you have to make sure that you read "create a variable-length argument list", and you'll learn the most important thing about variable-parameter methods, which is that we treat variable parameters as arrays.

So, to continue with the previous example, you can write the following code:

Public Guitar (String builder, string model,
Guitarwood Backsideswood, Guitarwood topwood,float nutwidth,
Guitarinlay fretboardinlay, Guitarinlay topinlay,string ... features) {
This.builder = Builder;
This.model = model;
This.backsideswood = Backsideswood;
This.topwood = Topwood;
This.nutwidth = Nutwidth;
This.fretboardinlay = Fretboardinlay;
This.topinlay = Topinlay;
for (String feature:features) {
SYSTEM.OUT.PRINTLN (feature);
}
}

Does the code above look attractive? But it does embody the essence of variable parameters. As another example, the following simple method calculates the maximum value from a set of numbers:

public static int Max (int-i, int ... rest) {
int max = i;
for (int i:rest) {
if (i > Max)
max = i;
}
return Max;
}

Isn't that simple enough?

So how do you store variable length parameters?

Because the Java compiler regards these as arrays, an array is clearly a good choice for storage, which will be reflected in example 5-2 below.

Example 5-2. To store a variable parameter as a member variable

Package com.oreilly.tiger.ch05;
public class Guitar {
Private String Builder;
Private String model;
private float nutwidth;
Private Guitarwood Backsideswood;
Private Guitarwood Topwood;
Private Guitarinlay Fretboardinlay;
Private Guitarinlay Topinlay;
Private string[] features;
Private static final float default_nut_width = 1.6875f;
Public Guitar (String builder, string model, String ... features) {
This (builder, model, NULL, NULL, default_nut_width, NULL, NULL, features);
}
Public Guitar (String builder, string model,
Guitarwood Backsideswood, Guitarwood Topwood,
Float Nutwidth, String ... features) {
This (builder, model, Backsideswood, Topwood, nutwidth, NULL, NULL, features);
}
Public Guitar (String builder, string model,
Guitarwood Backsideswood, Guitarwood Topwood,
Float Nutwidth,
Guitarinlay Fretboardinlay, Guitarinlay Topinlay,
String ... features) {
This.builder = Builder;
This.model = model;
This.backsideswood = Backsideswood;
This.topwood = Topwood;
This.nutwidth = Nutwidth;
This.fretboardinlay = Fretboardinlay;
This.topinlay = Topinlay;
This.features = features;
}
}

You can simply store these variable parameters in the Java Collection class.

Variable declaration
Private List features;
Writing in a method or in a constructor
This.features = Java.util.Arrays.asList (features);

Allow 0-length argument list

A notable feature of variable parameters is that variable-length parameters can accept 0 to n parameters. This means that you can call one of these methods without passing any arguments, and the program can run as well. On the other hand, it means that as a programmer, you'd better realize that you have to be on the lookout for this to happen.

How do you implement it?

Remember that in the repeating variable-length parameter class table, you read the following simple method:

public static int Max (int-i, int ... rest) {
int max = i;
for (int i:rest) {
if (i > Max)
max = i;
}
return Max;
}

You can invoke this method in many forms:

int max = Mathutils.max (1, 4);
int max = Mathutils.max (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int max = Mathutils.max (18, 8, 4, 2, 1, 0);

One thing that is not so satisfying is that in many cases, the number you are passing is already stored in an array, or at least in some form of integration:

Use this method to get the numbers

int[] numbers = Getlistofnumbers ();

It is not possible to pass these numbers to the Max () method. You need to check the length of the list to intercept the first object (if there is one), and then check the type to make sure it is int. Having done this, you can pass the entry method along with the rest of the array. The remaining parts of the array are repeated, or manually converted into suitable formats. In short, the process will be very hard, you need to do a lot of trivial things. To think about it, you remember that the compiler interprets this method as follows: public static int max (int-I, int[] rest)

So, you can make some adjustments and rewrite the Max () method as follows:

public static int max (int ... values) {
int max = Integer.min_value;
for (int i:values) {
if (i > Max)
max = i;
}
Return

You have now defined a method that can easily accept arrays.

Use this method to get the numbers
int[] numbers = Getlistofnumbers ();
int max = Mathutils.max (numbers);

When you accept a single variable length parameter, it is easy to use this method. However, if in the best case you pass a 0-length array, this can cause problems and you will get unpredictable results. In order to solve this problem, you need a small error check. Example 5-3 is a complete code listing for the Mathutils class, where it is a more powerful Mathutil class.

Example 5-3 method for handling 0 parameters

Package com.oreilly.tiger.ch05;
public class Mathutils {
public static int max (int ... values) {
if (Values.length = = 0) {
throw new IllegalArgumentException ("No values supplied.");
}

At any time, you might want to handle a 0-length argument list, and you'll need to perform this sort of error checking. In general, a powerful IllegalArgumentException class is a good choice.

int max = Integer.min_value;
for (int i:values) {
if (i > Max)
max = i;
}
return Max;
}
}

What about calling the same method to handle a method where the usual arguments are not arrays? This is, of course, perfectly legal. The following code is the means by which the max () method is legitimately invoked:

int max = Mathutils.max (myarray);
int max = Mathutils.max (new int[] {2, 4, 6, 8});
int max = Mathutils.max (2, 4, 6, 8);
int max = Mathutils.max (0);
int max = Mathutils.max ();

Specify object parameters, not basic types

In the fourth chapter we talked about the addition of Tiger to a series of new features by unpacking the box. You can use the object wrapper class in the parameters that your method accepts when dealing with variable parameters.

How to achieve it?

You must remember that all classes in Java are ultimately java.lang.Object subclasses. This means that any object can be converted into an object. Further, because basic types like int and short are automatically converted into their corresponding object wrapper classes (like integers and short), any Java type can be converted to an object.

So, if you need your variable parameter method to accept the most diverse types of parameters, then you can use the object type as the parameter type. Better yet, in most cases, object objects are used in order to achieve multiple functions. For example, write a method for printing.

Private String print (Object ... values) {
StringBuilder sb = new StringBuilder ();
for (Object o:values) {
Sb.append (o)
. Append ("");
}
return sb.tostring ();
}

The simplest meaning here is to print out everything. However, the more general definition of this method is the following:

private string Print (String ... values) {
StringBuilder sb = new StringBuilder ();
for (Object o:values) {
Sb.append (o)
. Append ("");
}
return sb.tostring ();
}

The problem with this approach is that the method itself cannot accept strings, integers, floating-point numbers, arrays, and other types of data that you want to print normally. By using the more general type of object, you can print everything.

Private String print (Object ... values) {
StringBuilder sb = new StringBuilder ();
for (Object o:values) {
Sb.append (o)
. Append ("");
}
return sb.tostring ();
}

Avoiding automatic conversion of arrays

Tiger has added various types of automatic conversions and conveniences that are very useful in most cases. Unfortunately, there are times when all these things become obstacles to you. In one case, when you convert multiple object objects into object[array objects in a variable parameter method, you will find that you need to write them in Java in individual cases.

How to achieve it?

Before you discuss this matter carefully, be sure you understand the problem. Java's new printf () method is a great convenience, as an example of this method:

System.out.printf ("The balance of%s ' s is $% (, 6.2f\n", Account.getowner (). Getfullname (), account.getbalance ());

If you look at the description of the printf () method in the Java document, you will see that it is a variable parameter method. It has two parameters: one is a string variable that is used to format strings, and the other is all object objects to be passed into the string:

PrintStream printf (String format, Object ... args)

Now, you can default the above code to the following form:

PrintStream printf (String format, object[] args)

Are the two kinds of writing exactly the same? Most of the cases are the same. Consider the following code:

object[] Objectarray = Getobjectarrayfromsomewhereelse (); out.printf ("Description of object array:%s\n", obj);

This is a bit far-fetched, but consider it a normal expense for introspective code. This is much simpler to write than other code. If you're writing a Code analysis tool, or an integrated development environment, or other things that might use a reflection or a simple API to determine what the application will need, these will soon become a common case. Here, you don't really care about the contents of an array of objects, just as you don't care about the array itself. What type is it? What is its memory address? What does its string mean? Keep in mind that all of these questions are related to the array itself, and the contents of the array are irrelevant. For example: Let's take a look at the following array code:

Public object[] Getobjectarrayfromsomewhereelse () {return new string[] {' Hello ', ' to ', ' all ', ' of ', ' You '};}

In this case, you will be able to write some code like the following to answer some questions about the array:

out.printf ("Description of object array:%s\n", obj);

However, the output is not what you would expect:

Run-ch05:[echo] Running Chapter 5 examples from Java tiger:a Developer ' s notebook[echo] Running varargstester ... [Java] Hello

What's going on here? This is not the result you want to see. However, the compiler did what it should do, and it put the object in the printf () method ... Convert to object[]. In fact, when the compiler gets a call to your method, it sees an argument that is object[]. So the compiler doesn't think of the array as an object itself, it's a different part. This is passed to the string format (%s) with the first argument part "Hello" string, so the result "Hello" is displayed.

To take a closer look at this, you need to tell the compiler that you want to think of the whole object array obj as a simple object, not a set of parameters. Take a look at the following bizarre code:

out.printf ("Description of object array:%s\n", new object[] {obj});

As a choice, there is a much simpler way:

out.printf ("Description of object array:%s\n", (object) obj);

In both cases, the compiler is no longer considered an array of objects, but is directly considered a simple object object, which happens to be an array of objects. Then the result will be as you wish (at least in this simple application):

Run-ch05:[echo] Running Chapter 5 examples from Java tiger:a Developer ' s notebook[echo] Running varargstester ... [Java] [Ljava.lang.String; @c44b88

If you see the results, you'll feel a little bit distracted. This is probably based on the results of reflection or other introspective code needs.



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.