Link Search Menu Expand Document

Pass by Value

Learning Objectives Covered

By the end of this leasson, you will be able to predict whether changes a method makes to its arguments will be visible to the caller.

Learning Materials

Time Commitment

Approximately 40-45 minutes


Read (Approximately 10-15 minutes)

JavaRanch has a good explanation. You don’t need to read their “Cup Size story.” You just need to realize that variables are like cups at Starbucks: they have names and sizes.


Watch (Approximately 15 minutes)

The “Is Java pass by reference or pass by value?” example video on YouTube does a good job of explaining, too. And it gives example code!


Try (Approximately 20 minutes)

Instructions: Carefully read and consider each question, then choose an answer by clicking it.

NOTE: Once you click on an answer choice, you will be presented with an explanation for that choice. Some questions may have more than one correct answer.


Question 1

Given this next() method:

public void next(int previous, int current) {
    int diff = current - previous;
    previous = current;
    current = current + diff;
}

Consider the following code:

int previous = 10;
int current = 13;
next(previous, current);
System.out.println(
    String.format("Finished %d, ready for %d", previous, current) );

What will be printed?

Choice A
Finished 10, ready for 16

Reassigning the reference to previous won’t work, but updating the value of current will.

:x: INCORRECT

The previous and current parameters are both primitive variables scoped to the next() method, so changes in the method will have no effect on the variables outside the method.

Choice B
Finished 13, ready for 16

Java passes the value of the reference to the int objects for prev and current, so their contents are updated in the next() method.

:x: INCORRECT

Since int is primitive, Java directly uses its value instead of creating a reference to it. The previous and current parameters to the next() method are different primitives than the main previous and current variables, and therefore hold completely unrelated values.

Choice C
Finished 10, ready for 13

Changes to primitives in a method don’t affect variables outside the method.

:heavy_check_mark: CORRECT!

Because the previous and current parameters of the next() method are primitive variables limited to the scope of the method, they are completely unrelated to any variables outside the method.



Question 2

Given the applyCoupons() method below:

public void applyCoupons(double[] prices) {
    for (int i = 0; i < prices.length; i++) {
        // 10% savings!
        prices[i] -= prices[i] * 0.1D;
    }
}

Consider the following code:

double[] costs = new double[2];
costs[0] = 10.0D;
costs[1] = 20.0D;
applyCoupons(costs);
System.out.println(
    String.format("Reduced prices: [%f, %f]", costs[0], costs[1]));

Will this print the following? Why?

Reduced prices: [10.0, 20.0]
Choice A Yes, because the prices parameter of applyCoupons() has a different name from the outside variable costs, so it doesn’t shadow costs. Therefore changes to prices will not be reflected in costs.

:x: INCORRECT

While prices does not shadow costs, they are not primitive values, so prices receives the value of the reference to costs. They both refer to the same array.

Choice B No, because prices and costs refer to the same object, so changes made to one are reflected in the other.

:heavy_check_mark: CORRECT

An array of doubles is not a primitive, so Java copies the value of its reference into the applyCoupons() parameter. Since prices now refers to the same array as costs, changes made in the method affect both variables.

Choice C Yes, because double is primitive, so changes made in the applyCoupons() method don’t affect variables outside the method.

:x: INCORRECT

While double is primitive, double[] is not. Therefore the prices parameter refers to the same array as costs.



Question 3

Assume that:

  1. A School has a findStudent() method that returns a Student when provided that student’s unique name.
  2. A GradeLevel enumeration has a next() method that returns the next expected grade (for instance, SEVENTH.next() returns EIGHTH).
  3. A Student includes a public field representing their GradeLevel.

Given the following graduate() method that advances a student’s grade level only if they passed the course:

public void graduate(Student student, boolean passed) {
    if (passed) {
        student.gradeLevel = student.gradeLevel.next();
    }
}

Consider this code:

Student student = School.findStudent("Goofus");
student.gradeLevel = GradeLevel.SEVENTH;
graduate(student, false);

student = School.findStudent("Gallant");
student.gradeLevel = GradeLevel.SEVENTH;
graduate(student, true);

Does either Goofus or Gallant advance to the eighth grade?

Choice A Yes, both Goofus and Gallant advance, because every student refers to the same object.

:x: INCORRECT

When we call student = School.findStudent('Gallant'); its existing reference to Goofus’s Student is removed, and it is assigned a reference to Gallant’s Student instead.

Choice B Yes, only Goofus advances. When graduate() is called the first time, the graduate() method’s parameter student is assigned to reference Goofus, so when it’s called the second time, Goofus is advanced.

:x: INCORRECT

At the end of the first call, the student variable that was referencing Goofus goes out of scope and disappears. The second time, it’s assigned to reference Gallant.

Choice C Yes, only Gallant advances. When graduate() is called the second time, it advances Gallant.

:heavy_check_mark: CORRECT

When graduate() is called the second time, the parameter student is assigned to the reference to Gallant. Therefore any changes made to the object are reflected outside the method.

Choice D No, neither Goofus nor Gallant advance. Because Java uses pass-by-value, the student information is copied into the student parameter. Since it’s a copy, changing it doesn’t change the outside variables.

:x: INCORRECT

While Java is pass-by-value, it doesn’t copy an entire object’s data. Instead, it copies a reference to object. Therefore, when graduate() changes student.gradeLevel, the object it references is changed.



Question 4

Given the following applyDiscount() method:

public double applyDiscount(double price, double discount) {
    price -= price * discount;
    return price;
}

Consider the following code:

double[] costs = new double[2];
costs[0] = 10.0D;
costs[1] = 20.0D;
costs[0] = applyDiscount(costs[0], 0.5D);
System.out.println(
    String.format("Altered prices: [%f, %f]", costs[0], costs[1]));

Why does this print the following?

Altered prices: [5.0, 20.0]
Choice A Mu! It doesn’t! Because double is primitive, changes made in the applyDiscount() method don’t affect variables outside the method.

:x: INCORRECT

While changes in applyDiscount() don’t affect variables outside, the calling code uses its return value to update costs[0].

Choice B Because the price parameter of applyDiscount() refers to the same object as costs[0], so changes to one are reflected in the other.

:x: INCORRECT

Since price and costs[0] are both primitive doubles, Java directly uses their values. Therefore they are entirely separate variables, and do not affect each other

Choice C Because even though updating price does not change costs[0], the reduced price is returned and assigned to costs[0] directly.

:heavy_check_mark: CORRECT

Since it returns the calculated value, the code can assign that to any variable it likes; and it does assign it to costs[0].