The JavaTM Tutorial

| Start of Tutorial > Start of Trail > Start of Lesson | Search

Trail: Learning the Java Language
Lesson: Objects and Classes in Java

## Passing Information into a Method

> When you write your method, you declare the number and type of the arguments required by that method. You declare the type and name for each argument in the method signature. 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 (presumably the future value of the loan is zero because at the end of the loan, you've paid it off):

> >     double computePayment(double loanAmt, double rate,
> >                                           double futureValue,
> >     				      int numPeriods) {
> >         double I, partial1, denominator, answer;

> >         I = rate / 100.0;
> >         partial1 = Math.pow((1 + I), (0.0 - numPeriods));
> >         denominator = (1 - partial1) / I;
> >         answer = ((-1 * loanAmt) / denominator)
> >                  - ((futureValue * partial1) / denominator);
> >         return answer;
> >     }

> This method takes four arguments: 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.

> As with this method, the set of arguments to any method is a comma-separated list of variable declarations where each variable declaration is a type/name pair:

> >     type name

> As you can see from the body of the `computePayment` method, you simply use the argument name to refer to the argument's value.

### Argument Types

> In Java, you can pass an argument of any valid Java data type into a method. 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 factory method that accepts an array as an argument. In this example, the method creates a new `Polygon` object and initializes it from a list of `Point`s (`Point` is a class that represents an x, y coordinate):

> >     static Polygon polygonFrom(Point[] listOfPoints) {
> >         . . .
> >     }

> Unlike some other languages, you cannot pass methods into Java methods. But you can pass an object into a method and then invoke the object's methods.

### Argument Names

> When you declare an argument to a Java method, you provide a name for that argument. This name is used within the method body to refer to the item.

> A method argument can have the same name as one of the class's member variables. If this is the case, then the argument is said to hide the member variable. Arguments that hide member variables are often used in constructors to initialize a class. For example, take the following `Circle` class and its constructor:

> >     class Circle {
> >         int x, y, radius;
> >         public Circle(int x, int y, int radius) {
> >             . . .
> >         }
> >     }

> The `Circle` class has three member variables: `x`, `y` and `radius`. In addition, the constructor for the `Circle` class accepts three arguments each of which shares its name with the member variable for which the argument provides an initial value.

> The argument names hide the member variables. So using `x`, `y` or `radius` within the body of the constructor refers to the argument, not to the member variable. To access the member variable, you must reference it through `this`--the current object:

> >     class Circle {
> >         int x, y, radius;
> >         public Circle(int x, int y, int radius) {
> >             this.x = x;
> >             this.y = y;
> >             this.radius = radius;
> >         }
> >     }

> Names of method arguments cannot be the same as another argument name for the same method, the name of any variable local to the method, or the name of any parameter to a `catch` clause within the same method.

### Pass by Value

> In Java methods, arguments are passed by value. When invoked, the method receives the value of the variable passed in. When the argument is of primitive type, pass-by-value means that the method cannot change its value. When the argument is of reference type, pass-by-value means that the method cannot change the object reference, but can invoke the object's methods and modify the accessible variables within the object.

> This is often the source of confusion--a programmer writes a method that attempts to modify the value of one its arguments and the method doesn't work as expected. Let's look at such method and then investigate how to change it so that it does what the programmer originally intended.

> Consider this series of Java statements which attempts to retrieve the current color of a `Pen` object in a graphics application:

> >     . . .
> >     int r = -1, g = -1, b = -1;
> >     pen.getRGBColor(r, g, b);
> >     System.out.println("red = " + r +
> >                        ", green = " + g +
> >                        ", blue = " + b);
> >     . . .

> At the time when the `getRGBColor` method is called, the variables `r`, `g`, and `b` all have the value -1. The caller is expecting the `getRGBColor` method to pass back the red, green and blue values of the current color in the `r`, `g`, and `b` variables.

> However, the Java runtime passes the variables' values (`-1`) into the `getRGBColor` method; not a reference to the `r`, `g`, and `b` variables. So you could visualize the call to `getRGBColor` like this: `getRGBColor(-1, -1, -1)`.

> When control passes into the `getRGBColor` method, the arguments come into scope (get allocated) and are initialized to the value passed into the method:

> >     class Pen {
> >         int redValue, greenValue, blueValue;
> >         void getRGBColor(int red, int green, int blue) {
> >             // red, green, and blue have been created
> >             // and their values are -1
> >             . . .
> >         }
> >     }

> So `getRGBColor` gets access to the values of `r`, `g`, and `b` in the caller through its arguments `red`, `green`, and `blue`, respectively. The method gets its own copy of the values to use within the scope of the method. Any changes made to those local copies are not reflected in the original variables from the caller.

> Now, let's look at the implementation of `getRGBColor` within the Pen class that the method signature above implies:

> >     class Pen {
> >         int redValue, greenValue, blueValue;
> >         . . .
> >             // this method does not work as intended
> >         void getRGBColor(int red, int green, int blue) {
> >             red = redValue;
> >             green = greenValue;
> >             blue = blueValue;
> >         }
> >     }

> This method will not work as intended. When control gets to the `println` statement in the following code, which was shown previously, `getRGBColor`'s arguments, `red`, `green`, and `blue`, no longer exist. Therefore the assignments made to them within the method had no effect; `r`, `g`, and `b` are all still equal to `-1`.

> >     . . .
> >     int r = -1, g = -1, b = -1;
> >     pen.getRGBColor(r, g, b);
> >     System.out.println("red = " + r +
> >                        ", green = " + g +
> >                        ", blue = " + b);
> >     . . .

> Passing variables by value affords the programmer some safety: Methods cannot unintentionally modify a variable that is outside of its scope. However, you often want a method to be able to modify one or more of its arguments. The `getRGBColor` method is a case in point. The caller wants the method to return three values through its arguments. However, the method cannot modify its arguments, and, furthermore, a method can only return one value through its return value. So, how can a method return more than one value, or have an effect (modify some value) outside of its scope?

> For a method to modify an argument, it must be of a reference type such as an object or array. Objects and arrays are also passed by value, but the value of an object is a reference. So the effect is that arguments of reference types are passed in by reference. Hence the name. A reference to an object is the address of the object in memory. Now, the argument in the method is referring to the same memory location as the caller.

> Let's rewrite the `getRGBColor` method so that it actually does what you want. First, you must introduce a new type of object, `RGBColor`, that can hold the red, green and blue values of a color in RGB space:

> >     class RGBColor {
> >         public int red, green, blue;
> >     }

> Now, we can rewrite `getRGBColor` so that it accepts an `RGBColor` object as an argument. The `getRGBColor` method returns the current color of the pen by setting the `red`, `green` and `blue` member variables of its `RGBColor` argument:

> >     class Pen {
> >         int redValue, greenValue, blueValue;
> >         void getRGBColor(RGBColor aColor) {
> >             aColor.red = redValue;
> >             aColor.green = greenValue;
> >             aColor.blue = blueValue;
> >         }
> >     }

> And finally, let's rewrite the calling sequence:

> >     . . .
> >     RGBColor penColor = new RGBColor();
> >     pen.getRGBColor(penColor);
> >     System.out.println("red = " + penColor.red +
> >                        ", green = " + penColor.green +
> >                        ", blue = " + penColor.blue);
> >     . . .

> The modifications made to the `RGBColor` object within the `getRGBColor` method affect the object created in the calling sequence because the names `penColor` (in the calling sequence) and `aColor` (in the `getRGBColor` method) refer to the same object.

| Start of Tutorial > Start of Trail > Start of Lesson | Search