In the Methods - Basics lesson we took a first look at using methods with some basic code examples and terminology to get a feel for how these members work. We then took a deeper look at passing information to a method using the concept of pass-by-value in the Methods - Passing Values lesson. In our final lesson on methods we examine method overloading and variable arguments.

When creating methods you can use the same method name more than once and this is known as overloading. When using overloading each method must have different parameter lists so the compiler knows which method to call. Having the same parameter types is fine as long as the order differs. Lets see some overloading in action :

``````
package info.java8;
/*
Test class for maths stuff
*/
public class MoreMathsStuff {

public static void main (String[] args) {
int aSquare = squareNumber(5);   // The return value will go into aSquare
System.out.println(aSquare);
float aFracSquare = squareNumber(12.2F);   // The return value will go into aFracSquare
System.out.println(aFracSquare);
}

/*
A method that squares and returns the passed integer
*/
static int squareNumber(int number) {
int square = number * number;
return square;  // Here we use the return keyword to pass back a value
}

/*
A method that squares and returns the passed float
*/
static float squareNumber(float number) {
float square = number * number;
return square;  // Here we use the return keyword to pass back a value
}
}

``````

The above screenshot shows the output of running our `MoreMathsStuff` class. The compiler knows which method to call from the argument list.

### Variable-Length Arguments Top

Variable-length arguments (varargs) were introduced in Java5 to give developers a way of defining a method with a parameter list that allowed a variable amount of arguments to be passed to it. In all previous versions of Java the only way to do this was through overloading or using an array. Overloading works fine when you have a small amount of argument combinations to pass and thus a small amount of overloaded methods. Using an array isn't the most elegant solution to this problem either as we have to declare an array size and we have no way of knowing the amount of arguments each time the method is called. So java came with varargs which allows us to define a parameter list that can vary dependant upon the arguments passed to it. We specify a varargs parameter using an ellipsis `...` between the type and name. Following are a few examples of the syntax:

``````
package info.java8;
int ... a
boolean ... b
String ... c

``````

The syntax tells the compiler that the method can be called with `0` or more arguments. The compiler also implicitly declares the defined varargs as an array of the correct size for the arguments and as such we can use array syntax on the parameter within the method.

There are a couple of rules about using varargs in our code:

1. When using varargs in a parameter list, the varargs parameter must be the last entry in the parameter list.
2. You can only have one varargs parameter in a parameter list.

Lets look at an example of using varargs:

``````
package info.java8;
/*
Test class for maths stuff
*/

public static void main (String[] args) {
int a = 12;
int b = 100;
int c = 97;
addNumbers();  // Call with no arguments
addNumbers(a);  // Call with 1 arguments
addNumbers(a, b);  // Call with 2 arguments
addNumbers(a, b, c);  // Call with 3 arguments
}

/*
A method that adds up the integers in a varargs list
*/
static void addNumbers(int ... number) {
for (int i=0; i<number.length; i++) {
System.out.println("Array position: " + i + ": " + number[i]);
}
System.out.println("Total = " + adder + "\n");
}
}

``````

The above screenshot shows the output of running our `NumberAdder` class. As you can see we can pass a variable number of arguments to the method.

We can overload methods that use varargs just like any other method:

``````
package info.java8;
/*
Test class for maths stuff
*/

public static void main (String[] args) {
int a = 12;
int b = 97;
int c = 100;
addNumbers();  // Call with no arguments
addNumbers(a);  // Call with 1 arguments
addNumbers(a, b);  // Call with 2 arguments
addNumbers(a, b, c);  // Call with 3 arguments
System.out.println("\n");
float d = 12.1F;
float e = 97.2F;
float f = 100.3F;
addNumbers();  // Call with no arguments
addNumbers(d);  // Call with 1 arguments
addNumbers(d, e);  // Call with 2 arguments
addNumbers(d, e, f);  // Call with 3 arguments
}

/*
A method that adds up the integers in a varargs list
*/
static void addNumbers(int ... number) {
for (int i=0; i<number.length; i++) {
System.out.println("Array position: " + i + ": " + number[i]);
}
}

/*
A method that adds up the floats in a varargs list
*/
static void addNumbers(float ... number) {
for (int i=0; i<number.length; i++) {
System.out.println("Array position: " + i + ": " + number[i]);
}
System.out.println("Total = ");
}
}

``````

The above screenshot shows the output of running our `NumberAdder2` class with overloaded methods. As you can see we can pass a variable number of arguments to the methods and the correct overloaded method is used.

Now lets think about this, varargs seem the business and used correctly they are. But there are pitfalls you need to be aware of when overloading with varargs and we will give a couple of examples here. Lets write a new class to highlight an example:

``````
package info.java8;
/*
Test class for maths stuff
*/
public class PrintStuff {

public static void main (String[] args) {
int a = 12;
printArray();  // Call with no arguments
printArray(a);  // Call with 1 arguments
String b = "fred" ;
printArray();  // Call with no arguments
printArray(b);  // Call with 1 arguments
}

/*
A method that Prints an array of ints
*/
static void printArray(int ... number) {
for (int i=0; i<number.length; i++) {
System.out.print("Array position: " + i + ": " + number[i]);
}
}

/*
A method that Prints an array of Strings
*/
static void printArray(String ... string) {
for (int i=0; i<string.length; i++) {
System.out.print("Array position: " + i + ": " + string[i]);
}
}
}

``````

The above screenshot shows the output of running our `PrintStuff` class with these overloaded methods. The compiler doesn't like this, but why?. Well lets think about it, when we pass the no-args list how can the compiler tell which method to go to, it can't so throws an ambiguous error.

Ok lets look at a different case with two parameters example:

``````
package info.java8;
/*
Test class for maths stuff
*/
public class PrintStuff2 {

public static void main (String[] args) {
String a = "wilma" ;
printArray();  // Call with no arguments
printArray(a);  // Call with 1 arguments
String b = "fred" ;
printArray();  // Call with no arguments
printArray(b);  // Call with 1 arguments
}

/*
A method that Prints one or more String
*/
static void printArray(String ... string) {
for (int i=0; i<string.length; i++) {
System.out.print("Array position: " + i + ": " + string[i]);
}
}

/*
A method that Prints one or more String
*/
static void printArray(String singleString, String ... string) {
for (int i=0; i<string.length; i++) {
System.out.print("Array position: " + i + ": " + string[i]);
}
}
}

``````

The above screenshot shows the output of running our `PrintStuff2` class with these overloaded methods. The compiler doesn't like this, but why?. When we pass the 1-args list how can the compiler tell which method to go to, the single `String` method or the `String ... string ` method passing an empty array; it can't so throws an ambiguous error.

`varargs` are a great way to cut down our code, just be aware of the pitfalls when overloading them. Often when we get ambiguity like that shown above its a design flaw.

## What's Next?

In the next lesson we look at instance variables and explain their scope.