Wednesday, February 10, 2010

Passing Information to a Method or a Constructor

Home Page > Learning the Java Language > Classes and Objects
Passing Information to a Method or a Constructor
The declaration for a method or a constructor declares the number and the type of the arguments for that method or constructor. For example, the following is a method that computes the monthly payments for a home loan, based on the amount of the loan, the interest rate, the length of the loan (the number of periods), and the future value of the loan:
public double computePayment(double loanAmt,                              double rate,                              double futureValue,                              int numPeriods) {     double interest = rate / 100.0;     double partial1 = Math.pow((1 + interest), -numPeriods);     double denominator = (1 - partial1) / interest;     double answer = (-loanAmt / denominator)                     - ((futureValue * partial1) / denominator);     return answer; } 
This method has four parameters: the loan amount, the interest rate, the future value and the number of periods. The first three are double-precision floating point numbers, and the fourth is an integer. The parameters are used in the method body and at runtime will take on the values of the arguments that are passed in.


Note: Parameters refers to the list of variables in a method declaration. Arguments are the actual values that are passed in when the method is invoked. When you invoke a method, the arguments used must match the declaration's parameters in type and order.

Parameter Types

You can use any data type for a parameter of a method or a constructor. This includes primitive data types, such as doubles, floats, and integers, as you saw in the computePayment method, and reference data types, such as objects and arrays.

Here's an example of a method that accepts an array as an argument. In this example, the method creates a new Polygon object and initializes it from an array of Point objects (assume that Point is a class that represents an x, y coordinate):

public Polygon polygonFrom(Point[] corners) {     // method body goes here } 


Note: The Java programming language doesn't let you pass methods into methods. But you can pass an object into a method and then invoke the object's methods.

Arbitrary Number of Arguments

You can use a construct called varargs to pass an arbitrary number of values to a method. You use varargs when you don't know how many of a particular type of argument will be passed to the method. It's a shortcut to creating an array manually (the previous method could have used varargs rather than an array).

To use varargs, you follow the type of the last parameter by an ellipsis (three dots, ...), then a space, and the parameter name. The method can then be called with any number of that parameter, including none.

public Polygon polygonFrom(Point... corners) {     int numberOfSides = corners.length;     double squareOfSide1, lengthOfSide1;     squareOfSide1 = (corners[1].x - corners[0].x)*(corners[1].x - corners[0].x)     + (corners[1].y - corners[0].y)*(corners[1].y - corners[0].y) ;     lengthOfSide1 = Math.sqrt(squareOfSide1);     // more method body code follows that creates      // and returns a polygon connecting the Points } 
You can see that, inside the method, corners is treated like an array. The method can be called either with an array or with a sequence of arguments. The code in the method body will treat the parameter as an array in either case.

You will most commonly see varargs with the printing methods; for example, this printf method:

public PrintStream printf(String format, Object... args) 
allows you to print an arbitrary number of objects. It can be called like this:
System.out.printf("%s: %d, %s%n", name, idnum, address); 
or like this
System.out.printf("%s: %d, %s, %s, %s%n", name, idnum, address, phone, email); 
or with yet a different number of arguments.

Parameter Names

When you declare a parameter to a method or a constructor, you provide a name for that parameter. This name is used within the method body to refer to the passed-in argument.

The name of a parameter must be unique in its scope. It cannot be the same as the name of another parameter for the same method or constructor, and it cannot be the name of a local variable within the method or constructor.

A parameter can have the same name as one of the class's fields. If this is the case, the parameter is said to shadow the field. Shadowing fields can make your code difficult to read and is conventionally used only within constructors and methods that set a particular field. For example, consider the followingCircle class and its setOrigin method:

public class Circle {     private int x, y, radius;     public void setOrigin(int x, int y) {         ...     } } 
The Circle class has three fields: x, y, and radius. The setOrigin method has two parameters, each of which has the same name as one of the fields. Each method parameter shadows the field that shares its name. So using the simple names x or y within the body of the method refers to the parameter, not to the field. To access the field, you must use a qualified name. This will be discussed later in this lesson in the section titled "Using thethis Keyword."

Passing Primitive Data Type Arguments

Primitive arguments, such as an int or a double, are passed into methods by value. This means that any changes to the values of the parameters exist only within the scope of the method. When the method returns, the parameters are gone and any changes to them are lost. Here is an example:
public class PassPrimitiveByValue {      public static void main(String[] args) {                 int x = 3;                 //invoke passMethod() with x as argument         passMethod(x);                 // print x to see if its value has changed         System.out.println("After invoking passMethod, x = " + x);             }          // change parameter in passMethod()     public static void passMethod(int p) {         p = 10;     } } 
When you run this program, the output is:
After invoking passMethod, x = 3 

Passing Reference Data Type Arguments

Reference data type parameters, such as objects, are also passed into methods by value. This means that when the method returns, the passed-in reference still references the same object as before. However, the values of the object's fields can be changed in the method, if they have the proper access level.

For example, consider a method in an arbitrary class that moves Circle objects:

public void moveCircle(Circle circle, int deltaX, int deltaY) {     // code to move origin of circle to x+deltaX, y+deltaY     circle.setX(circle.getX() + deltaX);     circle.setY(circle.getY() + deltaY);       //code to assign a new reference to circle     circle = new Circle(0, 0); } 
Let the method be invoked with these arguments:
moveCircle(myCircle, 23, 56) 
Inside the method, circle initially refers to myCircle. The method changes the x and y coordinates of the object that circle references (i.e.,myCircle) by 23 and 56, respectively. These changes will persist when the method returns. Then circle is assigned a reference to a new Circleobject with x = y = 0. This reassignment has no permanence, however, because the reference was passed in by value and cannot change. Within the method, the object pointed to by circle has changed, but, when the method returns, myCircle still references the same Circle object as before the method was called.

We welcome your participation in our community. Please keep your comments civil and on point. You may optionally provide your email address to be notified of replies — your information is not used for any other purpose. By submitting a comment, you agree to these Terms of Use.

Echo 30 Items
Admin
Guest
I am puzzled about the example of Arbitrary Number of Arguments. When the method "polygonFrom(Point... corners)" is called with no parameter, the corners[1].x will not exist. Does it cause errors?
Wednesday, July 29, 2009, 05:25:28
FlagLikeReply
negora
The problem with the arbitrary number of arguments it's indeed that you need to control the number of parameters which have really passed to the method. Maybe in that example they should add a conditional statement which forces a minimum of 2 arguments, but I believe that since it's just an example, they decided not to complicate it more.
Thursday, August 06, 2009, 13:27:39
FlagLikeReply
otherGuest
and I am puzzled about the example in "parameter names":

public class Circle {
private int x, y, radius;
public void setOrigin(int x, int y) {
...
}
}

x and y are said to be parameters, but to me they seem to be local variables.
Also, they are not set to any value, so how can we call the method setOrigin using them?
Thursday, July 30, 2009, 07:23:06
FlagLikeReply
negora
That example is a demonstration to clarify why it's not good to employ the same name for fields/attributes that for arguments/parameters. There're 2 fields called x and y which are declared here:

private int x, y, radius;

However, the method uses 2 parameters which have exactly the same name that 2 of the already declared fields:

public void setOrigin (int x, int y) {

Taking that into account, if you print the value of x and y inside of that method, you will print the value of the passed arguments but NEVER the ones which correspond to the fields (which, by the way, would cause an error because they have not been initialized):

public void setOrigin (int x, int y) {
System.out.print (x);
System.out.print (y);
}

If you wanted to work with the fields of the class (the variables declared out of the method), you would need to use the keyword "this":

public void setOrigin (int x, int y) {
this.x = x;
this.y = y;
}

However the use of the keyword "this" is explained later in this guide ;) .
Thursday, August 06, 2009, 13:42:46
FlagLikeReply
Liked by
Guest
Guest
negora
By the way, that line which you think it's a call to the method it's a declaration, not a call. It's not that he's passing the fields x and y of the class Circle to the method.
Thursday, August 06, 2009, 13:51:53
FlagLikeReply
Brandon Ca
they are parameters for the function declaration, but for the definition they are parameters and variables
Friday, December 11, 2009, 12:36:55
FlagLikeReply
Brandon Ca
Since Java Wraps C i think this example will help you to understand...

#include

void byvalue(int a)
{
printf("\nthe address of value a is 0x%X \n",&a);
// a copy was created.
printf("\nthe value of a is %d \n",a);
a = 6;
printf("\nthe value of a is %d \n", a);
}

void bypointer(int *a)
{ // copy was not created.
printf("\nthe address that pointer a holds is 0x%X\n",a);

// a pointer with the star is dereferenced (shows the value it points to)
// without a star exposes the address it holds.
// a pointer is a variable that holds anothers address
printf("\nthe value pointer a points to is %d \n",*a);
*a = 4;
}




int main(void)
{
int x;
x = 3;
printf("\nthe address of x is 0x%X\n",&x);

byvalue(x);
printf("\n%d is the value of x \n", x);

bypointer(&x);
printf("\n%d is the value of x \n", x);

return 0;
}


[brandon@localhost ~]$ ./tester

the address of x is 0x6968986C

the address of value a is 0x6968984C

the value of a is 3

the value of a is 6

3 is the value of x

the address that pointer a holds is 0x6968986C

the value pointer a points to is 3

4 is the value of x
[brandon@localhost ~]$
Friday, December 11, 2009, 12:26:53
FlagLikeReply
Marq
Negora, you are correct in most of your response, except for the fact this line: "which correspond to the fields (which, by the way, would cause an error because they have not been initialized)". The instancevariables/fields do not need to be initialized to a value when declared (the same isn't true for local variables). If no value is declared, then the default value will be provided. Since they are declared as int, the default value will be 0.
Thursday, August 20, 2009, 22:13:50
FlagLikeReply
Brandon Ca
that is not true... in global variables if they are uninitialized they are set to zero that is called the BSS Section. Local could become any value.
Friday, December 11, 2009, 12:39:48
FlagLikeReply
Brandon Ca
Java Wraps C
Friday, December 11, 2009, 12:41:44
FlagLikeReply
alora
Hey there,
I'm confused about the last paragraph about passing reference data type arguments.
If this last line in the method [ circle = new Circle (0, 0); ] wouldn't be there, would the changes then persist?
What's the difference between the permanent change and the change only within the method?
Monday, September 14, 2009, 08:46:04
FlagLikeReply
Guest
ye bhi aata kya
Wednesday, September 16, 2009, 13:09:42
FlagLikeReply
Liked by
Guest
Gaz@UWE
i agree, the addition of the line circle = new Circle (0, 0) makes the example confusing!
but in short, the changes to myCircle do persist after the method has finished.

that line of code simply over-writes the reference to myCircle, that is stored in the circle variable, with a reference to a newly created circle object,
so circle no longer references the external object myCircle,
so any modifications to circle *from that point forward* will not persist when the method terminates.
Friday, September 18, 2009, 23:43:39
FlagLikeReply
Guest
thanks Gaz, now is very clear
Friday, September 25, 2009, 09:39:41
FlagLikeReply
Andrew
I am having trouble declaring a variable with an arbitrary number of arguments. I am trying to write a "polygon" program similar to the example above. Here are the first two lines:

public class Polygon {
Point2[] corners=new Point2[];

where Point2 is an object with this code:

public class Point2 {
double x,y;
public Point2(double x, double y) {
this.x=x;
this.y=y;
}

I get the following error:

Polygon.java:2: array dimension missing

How do you declare a variable to be used fro an arbitrary number of arguments?

Thank You fro Responding
Tuesday, September 29, 2009, 12:49:31
FlagLikeReply

No comments:

Post a Comment