Skip to content

VOL 01 / CH 05 / LESSON 08

5.8 Lab: Methods, Pass-by-Value, and Overloading ​

Prerequisites: Method declarations, parameters, return values, call stacks, and overloading

Estimated time: 50 minutes

Practice environment: JDK 17+ and Bash; all files stay in a temporary directory

You are ready to continue when: You have completed four required experiments and explain the call contract

bash
chapter5_lab_root=$(mktemp -d)
readonly chapter5_lab_root
mkdir -p "$chapter5_lab_root/chapter05-lab/out"
cd "$chapter5_lab_root/chapter05-lab"

Required Exercise 1: Pure Computation ​

Save as NumberTools.java:

java
public class NumberTools {
    static boolean isEven(int value) {
        return value % 2 == 0;
    }

    static int maxOfThree(int first, int second, int third) {
        return Math.max(first, Math.max(second, third));
    }

    static int digitSum(int value) {
        long remaining = Math.abs((long) value);
        int sum = 0;
        do {
            sum += (int) (remaining % 10);
            remaining /= 10;
        } while (remaining > 0);
        return sum;
    }

    public static void main(String[] args) {
        System.out.println(isEven(-4));
        System.out.println(maxOfThree(3, 9, 5));
        System.out.println(digitSum(-2147483648));
    }
}
bash
javac -d out NumberTools.java
java -cp out NumberTools

Expected to be true, 9, and 47. digitSum first converts to long and then takes the absolute value, avoiding the boundary where Math.abs(Integer.MIN_VALUE) remains negative.

Required Exercise 2: Demonstrate Pass-by-Value ​

Save as PassingLab.java:

java
import java.util.Arrays;

public class PassingLab {
    static void changePrimitive(int value) {
        value = 99;
    }

    static void mutateArray(int[] values) {
        values[0] = 99;
    }

    static void replaceArray(int[] values) {
        values = new int[] {7, 8};
    }

    public static void main(String[] args) {
        int count = 1;
        int[] numbers = {1, 2};

        changePrimitive(count);
        mutateArray(numbers);
        replaceArray(numbers);

        System.out.println(count);
        System.out.println(Arrays.toString(numbers));
    }
}
bash
javac -d out PassingLab.java
java -cp out PassingLab

Expected:

text
1
[99, 2]

Explain by stating "What values were copied, and whether the two variables identify the same object," without using the erroneous shortcut "arrays are passed by reference."

Required Exercise 3: Overload Resolution ​

Save as OverloadLab.java:

java
public class OverloadLab {
    static String pick(long value) {
        return "long";
    }

    static String pick(Integer value) {
        return "Integer";
    }

    static String pick(int... values) {
        return "varargs";
    }

    static String describe(Object value) {
        return "object";
    }

    static String describe(String value) {
        return "string";
    }

    public static void main(String[] args) {
        Object value = "iron";
        System.out.println(pick(1));
        System.out.println(pick());
        System.out.println(describe(value));
        System.out.println(describe("iron"));
    }
}
bash
javac -d out OverloadLab.java
java -cp out OverloadLab

Expected: long, varargs, object, string. Record the static argument types at each call site and the applicable phase.

Required Exercise 4: Stack Trace ​

Save as TraceLab.java:

java
public class TraceLab {
    static void loadOrder() {
        parseQuantity();
    }

    static void parseQuantity() {
        Integer.parseInt("many");
    }

    public static void main(String[] args) {
        loadOrder();
    }
}
bash
javac -d out TraceLab.java
trace_status=0
java -cp out TraceLab || trace_status=$?
test "$trace_status" -ne 0

The process should exit with a non-zero status and print NumberFormatException. From parseQuantity, loadOrder to main, mark the business call chain; error messages and JDK internal frames may vary with versions.

Optional Exercise 1: Bounded Recursion ​

java
static long factorial(int value) {
    if (value < 0) {
        throw new IllegalArgumentException("negative value");
    }
    if (value > 20) {
        throw new ArithmeticException("factorial exceeds long: " + value);
    }
    if (value <= 1) {
        return 1L;
    }
    return Math.multiplyExact(value, factorial(value - 1));
}

Test 0, 1, 5, 20, 21, and -1. The factorial of 21 exceeds long, so the input check rejects it immediately; negative values violate the input domain. Also pass Integer.MAX_VALUE and verify that it is rejected before recursion starts.

Optional Exercise 2: Consolidate Default Parameters ​

java
static String describeItem(String name) {
    return describeItem(name, 1, false);
}

static String describeItem(String name, int level) {
    return describeItem(name, level, false);
}

static String describeItem(String name, int level, boolean rush) {
    if (name == null || name.isBlank()) {
        throw new IllegalArgumentException("name is blank");
    }
    if (level < 1) {
        throw new IllegalArgumentException("level: " + level);
    }
    return name + ":" + level + ":" + rush;
}

Verify that all overloads follow the same validation. Then consider whether rush should be changed to an enum.

Fault Experiment ​

Turn on each one individually and record the first diagnostic:

java
// static int convert(int value) { return value; }
// static long convert(int number) { return number; } // Change only the return type
java
// static void print(String value) { }
// static void print(Integer value) { }
// print(null); // Ambiguity
java
// static int missingReturn(boolean flag) {
//     if (flag) return 1;
// }

Distinguish between duplicate signatures, overload ambiguity, and the normal path lacking a return value.

Safe Cleanup ​

bash
pwd
test ! -e out || rm -r -- out

Confirm that the files are located in this experiment directory and delete only the artifacts produced in this chapter.

Acceptance and Cleanup ​

Add zero and negative-input cases for the pure methods, retaining the Integer.MIN_VALUE case, and that array experiments can be explained using "reference value copies." Be able to describe the selection phase for each of the four overloads. Stack traces must be traced back from the point where an exception is exposed to main. Three types of faults should be marked separately as duplicate signatures, call ambiguity, and missing return paths. After saving the records, clean up the temporary directory:

bash
cd
ls -ld -- "$chapter5_lab_root"
rm -r -- "$chapter5_lab_root"

Paths for methods and recursion have already been verified. The next chapter will place a group of values of the same type into a contiguous index space.

→ Next: Array Basics

Built with VitePress | Software Systems Atlas