Java Methods and Program Decomposition

Learn to write your own static methods in Java and to build programs out of them. Define and call methods, pass information in through parameters and get results back with return. Find out where each variable can be used, why a method works on copies of its arguments, and how the call stack keeps track of running methods. Overload methods and predict which version Java calls. Finally, divide a problem into small methods that each do one thing, remove repeated code and build and test a program one method at a time.

BeginnerLesson 3 of 11 in Object-Oriented Programming with Java Course

What you will learn

  1. Define static methods, call them from main and from each other, and give them the information they need through parameters.
    • Define a method and call it
      Write a method header and body in the right place, call the method by name, and follow how execution jumps into the method and back.
    • Pass information to a method with parameters
      Declare parameters with a type and a name, call the method with matching arguments, and use several parameters in the right order.
  2. Write methods that compute a value and hand it back with return, and use returned values in variables, expressions and conditions.
    • Return a value and use it
      Declare a return type, send a result back with a return statement, and decide in the calling code what happens with the returned value.
    • Return from inside conditions and loops
      Use return statements inside if statements and loops, make sure every path returns a value, and write methods that answer a yes-or-no question.
  3. Know where each variable can be used, what a method can and cannot change in the code that calls it, and how the call stack keeps track of running methods.
    • Know where each variable can be used
      Apply the scope rules for local variables, parameters and variables declared in blocks, and fix the compiler errors that scope mistakes cause.
    • Understand that arguments are passed as copies
      Predict what a method can change in the code that calls it: the method works on copies of the argument values, so reassigning a parameter does not change the caller's variable.
    • Trace method calls on the call stack
      Follow how Java records running methods in stack frames, trace programs in which methods call other methods, and read a stack trace.
  4. Give several methods the same name with different parameter lists, and predict which version Java calls for a given set of arguments.
    • Write overloaded methods
      Declare methods that share a name, know which differences make a valid overload, and use overloading where the methods do the same job.
    • Predict which overloaded method runs
      Work out which version Java chooses from the arguments' types, including automatic widening, and recognize calls that do not compile.
  5. Break a problem into small methods that each do one thing, replace repeated code with parameterized methods, and build and test a program one method at a time.
    • Give each method one clear job
      Recognize a well-divided program, split code that does too much, and keep calculation separate from input and output.
    • Replace repeated code with a parameterized method
      Find code that is repeated with small differences, turn it into one method whose parameters carry the differences, and check that the program still behaves the same.
    • Design a program top-down and test it method by method
      Plan a program as a sequence of method calls, write it step by step with temporary stubs, and test each method with inputs whose results you know.

Java Methods study guide

5 chapters

1

Write and call your own methods

A program becomes easier to follow when meaningful steps have names. A method gives a group of statements one name, and a call runs those statements at the point where they are needed. Start with a method that always prints the same line, then add parameters so one definition can handle different inputs. Reading a header and matching it to a call lets you see what information each step needs before you inspect its body.

1.1 Define a method and call it

A method is a named block of statements that performs a task. Defining a method makes that task available; calling it makes the task run.

Read the header and body
public static void printLine() {
    System.out.println("----------");
}

The first line is the header. Read its parts from left to right:

  • public allows code in other classes to call the method.
  • static makes the method belong to the class. No object is needed to call it.
  • void says the method returns no value.
  • printLine names the task.
  • () is the empty parameter list: this method needs no input.

The braces enclose the body, the statements that run on a call. There is no semicolon between this header and its opening brace.

Put the definition in the class
public class Main {
    public static void main(String[] args) {
        System.out.println("Start");
        printLine();
        System.out.println("Middle");
        printLine();
    }

    public static void printLine() {
        System.out.println("----------");
    }
}

main and printLine are separate methods inside Main. The closing brace of main comes before the definition of printLine. A method cannot be defined inside another method; a misplaced brace can produce "illegal start of expression".

Definitions may appear in either order. Moving printLine above main does not change when it runs. A method that is never called does not run just because its definition appears in the file.

Follow a call and the return to the caller

The call printLine(); consists of the name, parentheses, and a semicolon because the call is a statement on its own. Execution starts in main:

  1. Print "Start".
  2. Enter printLine, print ten dashes, then continue after the call.
  3. Print "Middle".
  4. Enter printLine again and print ten dashes again.

The output is:

Start
----------
Middle
----------

Both calls use the same definition. Changing its printed line changes both places that use it.

Name and call methods accurately

Use a verb or verb phrase in camelCase, starting with a lowercase letter: printReceipt, calculateAverage, or isValidCode. Java treats uppercase and lowercase as different: PrintLine() cannot find a method named printLine. Writing printLine; also fails; the parentheses are part of the call.

For a static method in another class, write the class name first. Math.max(3, 8) gives 8, Math.abs(-4) gives 4, and Math.sqrt(16.0) gives 4.0. Your own methods in the same class can be called by name alone.

These examples use the classic class-based form with public static void main(String[] args). Java 25 also supports compact source files with void main() and no surrounding class. Keep the classic form when running these examples; its helper methods are declared static. Methods such as System.out.println that you call from Java's library need not themselves be static.

Key Takeaways

  • Place method definitions inside the class and outside other methods.
  • A definition makes a task available; a call runs it and then continues in the caller.
  • Write parentheses on a call and a semicolon when the call is a statement.
  • Use a descriptive camelCase name and match its capitalization exactly.
  • Call another class's static method with its class name, such as Math.max(3, 8).

1.2 Pass information to a method with parameters

A parameter lets one method handle values that change from call to call. An argument is the value supplied for that parameter when the method is called.

Give each input a type and a name
public static void printStars(int count) {
    for (int i = 0; i < count; i++) {
        System.out.print("*");
    }
    System.out.println();
}

int count declares one parameter. In printStars(3);, the argument 3 becomes the starting value of count. The loop runs three times, so it prints ***, then println() ends the line. printStars(8); uses the same body with count equal to 8.

The type is written in the definition, not in the call. Write printStars(5);, not printStars(int 5);.

Evaluate arguments before entering the body

An argument can be a literal, a variable, or an expression:

int n = 4;
printStars(n * 2);

Java evaluates n * 2 first. It passes the resulting value 8, so the body starts with count equal to 8. The caller's variable name does not have to match the parameter's name.

Match several parameters by position

Each parameter needs its own type. A rectangle method can start with this header:

public static void printRectangle(int width, int height)

The call printRectangle(5, 2); gives width the value 5 and height the value 2. Reversing the arguments gives a rectangle 2 wide and 5 high. Both calls compile because both arguments are ints; only the intended shape tells you which order is right. Writing (int width, height) in the header fails because height has no declared type.

Different types make some ordering mistakes easier to catch:

public static void printRepeated(String text, int times) {
    for (int i = 0; i < times; i++) {
        System.out.print(text);
    }
    System.out.println();
}

printRepeated("ab", 3); prints "ababab". printRepeated(3, "ab"); cannot match a String followed by an int. The number of arguments must also match: printRectangle(5); leaves one parameter without a value.

Check compatible numeric types

Java automatically widens an int to a double. A method with parameters (double km, double hours) accepts the arguments (150, 2), giving it 150.0 and 2.0. Every int value can be represented exactly as a double.

Java does not implicitly narrow a double argument to an int parameter. printStars(2.9); fails because converting it would lose the fractional part. The explicit cast in printStars((int) 2.9); produces 2, so two stars are printed. Use a cast only when dropping that part is the intended behavior.

Choose a parameter for each piece of information the task needs. Receiving text and a count makes printRepeated usable from keyboard input, a fixed test call, or another method. Its body does not have to decide where those values came from.

Key Takeaways

  • A parameter is declared in a header; an argument supplies its value in a call.
  • Java evaluates argument expressions before running the called method.
  • Arguments match parameters by position, count, and compatible type.
  • Write a type for every parameter, but no types in the call.
  • An int can widen to double; a double needs an explicit cast to become an int.
  • Swapping same-type arguments can compile and still change the result.
2

Return results from methods

A method can do more than print: it can give a value back to the code that called it. That makes a calculation usable in another calculation, a condition, or a later report. Follow how return types, expressions, and assignments fit together, then use returns inside decisions and searches. The position of a return matters: it decides both which answer reaches the caller and how much of the method gets a chance to run.

2.1 Return a value and use it

A return value is a result sent from a method to its caller. Once a call finishes, the call can be used as an expression with that result's type.

Declare what comes back
public static int sum(int a, int b) {
    return a + b;
}

int replaces void in the header because this method gives back an integer. The return statement evaluates a + b and sends the value to the call site. For sum(4, 7), that value is 11.

The caller decides what happens next:

int total = sum(4, 7);
System.out.println(sum(4, 7));
int doubled = sum(2, 3) * 2;

The first line stores 11; the second prints 11; the third stores 10. A returned value can also be used in a condition, such as if (sum(a, b) > 10).

A compatible int result may widen when returned from a double method. A double result cannot be returned from an int method without a suitable explicit conversion.

Calculate the expression before converting the result
public static double average(int a, int b) {
    return (a + b) / 2.0;
}

For average(3, 4), the numerator is 7. Dividing by the double literal 2.0 gives 3.5. If the expression were (a + b) / 2, Java would first divide two ints and get 3. Only then would it widen that value to the returned 3.0. A double return type does not repair integer division already performed inside the body.

Separate returning from printing
Method behaviorWhat the caller receivesWhat appears on screen
return a + b; in an int methodThe sumNothing from this statement
System.out.println(a + b); in a void methodNo valueThe sum

A void call cannot fill a value in an assignment or another call. If printSum is void, int total = printSum(1, 2); fails even though printSum prints a number. Use a value-returning method for calculations and let the caller choose whether to print.

Return text and yes-or-no results

Return types also include String and boolean. A greeting method can return "Hello, " + name + "!", giving "Hello, Ana!" for the argument "Ana". An isEven(int n) method can return n % 2 == 0.

A formatter turns a number into reusable text:

public static String formatDuration(int minutes) {
    return minutes / 60 + " h " + minutes % 60 + " min";
}

For 135, integer division gives 2 whole hours and the remainder gives 15 minutes. The result is "2 h 15 min"; for 60, it is "1 h 0 min".

Keep or combine the result

A call such as sum(4, 7); compiles, but discards its result. If square(x) returns a new value, use x = square(x); to store it in x.

A result can also become an argument immediately. In Math.max(sum(1, 2), 4), sum(1, 2) first gives 3, then Math.max(3, 4) gives 4. Evaluate the inner call before using its result in the outer one.

Key Takeaways

  • The declared return type tells the caller what kind of result the call supplies.
  • Returning supplies a value; printing displays a value.
  • The expression is calculated before its result is converted to the return type.
  • Store a returned value when later code needs it; a standalone call discards it.
  • A returned value can be an argument to another method.

2.2 Return from inside conditions and loops

A return statement ends the current method call immediately. Inside a condition or a loop, it still leaves the whole method, not just that block.

Give each route an answer
public static int larger(int a, int b) {
    if (a > b) {
        return a;
    }
    return b;
}

larger(9, 4) returns 9 from inside the if. For larger(2, 6), the if body is skipped and the final return gives 6. Equal inputs such as (5, 5) also reach the final return, giving 5. No else is needed after the first return because that route has already left the method.

In an ordinary value-returning method, no possible route may reach the closing brace without supplying a value. A sign method that returns only for positive and negative inputs leaves zero without an answer:

public static String sign(int n) {
    if (n > 0) {
        return "positive";
    } else if (n < 0) {
        return "negative";
    }
    return "zero";
}

The final return completes the method. Two separate if statements, one testing n > 0 and one testing n <= 0, still need a final return or a clear if/else structure. Java's return check does not infer that those two comparisons cover all integers. A statement directly after an unconditional return in the same block is unreachable and is rejected.

Finish a search at the right moment
public static int firstMultipleOf7(int start, int end) {
    for (int i = start; i <= end; i++) {
        if (i % 7 == 0) {
            return i;
        }
    }
    return -1;
}

For (10, 20), the loop rejects 10, 11, 12, and 13, then returns 14. The call ends without checking 15 through 20. For (15, 20), the loop finishes without a match, so the return after it gives -1, the agreed "not found" signal.

Putting else { return -1; } inside the loop would quit after the first failed candidate. The search from 10 would then report failure before reaching 14. Failure belongs after all candidates have been tried.

Return the condition itself

A comparison already produces a boolean. Write return n % 2 == 0; instead of an if/else that returns true and false separately. A boolean method's name often starts with is or has, so a call reads naturally inside an if.

public static boolean isLeapYear(int year) {
    return (year % 4 == 0 && year % 100 != 0)
        || year % 400 == 0;
}

This returns true for 2024 and 2000, but false for 1900 and 2023. Use if (isLeapYear(y)) directly.

Leave a void method early

A void method uses return; without a value. For example, printSquareRoot(double x) can print "No real square root" and return immediately for a negative input. For other inputs it can print Math.sqrt(x), which gives 1.5 for 2.25. Writing return 5; in a void method fails because its header promises no returned value.

Key Takeaways

  • return ends the current call immediately, including a return inside a loop.
  • A value-returning method must not reach its closing brace without an answer.
  • Put a search's failure return after the loop, so later candidates can be checked.
  • A comparison can be returned directly as a boolean.
  • Use return; with no value to leave a void method early.
  • Code directly after an unconditional return in the same block is unreachable.
3

Follow variables and calls through a program

A method call does not give a helper access to every variable in the program. Each call has its own parameters and local variables, and Java keeps those values in a separate stack frame. Use scope to decide where a name is legal, pass by value to predict what assignments can change, and the call stack to track unfinished work. These three ideas explain why two variables can have the same name while holding different values.

3.1 Know where each variable can be used

A variable's scope is the region of code where its name can be used. Start with the braces around its declaration: a local name belongs to a particular method or block.

A caller's locals stay in the caller
public static void main(String[] args) {
    int price = 20;
    printDouble(price);
}

public static void printDouble(int price) {
    System.out.println(price * 2);
}

The price in main and the parameter price in printDouble are separate variables. The argument supplies the value that the helper needs, so the helper prints 40.

Removing the parameter and calling printDouble() does not let the helper read main's local price. Its body would fail with "cannot find symbol". Calling one method from another does not join their scopes. Different methods may each use the name count without linking their variables.

A nested block makes a smaller scope

A local variable can be used from its declaration through the closing brace of its block. A parameter is available throughout its method body. A counter declared in for (int i = 0; i < 3; i++) belongs to that loop; i cannot be read afterward.

To keep a result after a loop, declare it before the loop:

int sum = 0;
for (int i = 1; i <= 5; i++) {
    sum += i;
}
System.out.println(sum);

The additions take sum through 1, 3, 6, 10, and 15. The final print can read sum because the surrounding block has not ended. i is needed only for the loop and stays inside its scope.

Moving int sum = 0; into the loop body creates a new sum on every pass. Each one starts at zero and disappears at the end of that pass. It cannot hold a running total or be printed after the loop.

Check names and starting values separately

Two locals with the same name cannot have overlapping scopes inside one method. A method with a parameter x cannot declare another local x; a loop that declares i cannot declare another i in its body. Rename the second variable or use the existing one.

Two loops one after the other may each declare int i. The first loop's scope has ended before the second declaration. Braces, not the whole file, determine that reuse.

A legal name also needs a value before it is read. int total; total++; fails because ++ must read the old value, and a local variable gets no automatic starting value. Use int total = 0; for a running total.

Keep a local variable in the smallest block that needs it. If a method needs information from its caller, make that information a parameter. If the caller needs a result, return it. Then the method's header and body show where its data comes from.

Key Takeaways

  • A local name is available from its declaration to the end of its block.
  • A called method cannot read the caller's local variables by name.
  • Declare an accumulator before a loop when it must retain a total or be read afterward.
  • Local names cannot overlap within one method, and locals need values before use.

3.2 Understand that arguments are passed as copies

Java passes arguments by value. At the start of a call, each parameter receives a copy of its argument's value. Assigning to the parameter changes that local variable.

Trace the copy separately
public static void main(String[] args) {
    int score = 10;
    addBonus(score);
    System.out.println(score);
}

public static void addBonus(int score) {
    score = score + 5;
    System.out.println(score);
}

There are two variables called score. Trace their values at each point:

Momentmain's scoreaddBonus's score
Before the call10No call yet
At entry to addBonus1010
After the helper's assignment1015
After the helper returns10Call has ended

The helper prints 15, then main prints 10. Sharing a name does not make the two variables share storage. Renaming the parameter would not change this behavior.

Return the new value and store it
public static int addBonus(int score) {
    return score + 5;
}

With this version, write score = addBonus(score);. Java copies the old value into the parameter, computes 15, returns it, and assigns it to the caller's variable. The assignment in the caller is the step that changes that variable.

A result can also be stored elsewhere. If triple(int n) multiplies its local n by 3 and returns it, then int a = 4; int b = triple(a); leaves a equal to 4 and gives b the value 12. Printing a + " " + b displays "4 12".

Apply the same rule to String references

A String variable holds a reference to a String object. Java copies that reference into a String parameter:

public static void exclaim(String text) {
    text = text + "!";
}

If the caller's word refers to "hi", exclaim(word); leaves word referring to "hi". Concatenation creates a new String, and the assignment changes only what the parameter refers to. Strings cannot have their existing contents changed.

To keep the new text, return text + "!" from a String method such as exclaimed, then write word = exclaimed(word);.

For mutable objects, such as lists, a copied reference can still point to the same object. A method can change that object's contents through the copied reference. Reassigning the parameter still cannot make the caller's variable refer to a different object. The copied-reference rule and the copied-number rule are both pass by value.

You may reassign a parameter, but a separate local such as result can make a longer calculation easier to read: it keeps the original input available while showing which value will be returned.

Key Takeaways

  • Each parameter receives a copy of its argument's value.
  • Reassigning a parameter leaves the caller's variable unchanged.
  • To keep a computed replacement, return it and assign it in the caller.
  • A copied object reference can reach the same mutable object, but parameter reassignment stays local.

3.3 Trace method calls on the call stack

The call stack records calls that have started but have not yet finished. Each call gets a stack frame with its parameters, local variables, and the place where its caller will continue.

Push a frame, finish it, then pop it

The stack works last in, first out. The newest call is on top and runs while its caller waits below it. When it returns, Java removes its frame and resumes the caller.

public static void main(String[] args) {
    int total = totalSeconds(2, 30);
    System.out.println(total);
}

public static int totalSeconds(int minutes, int seconds) {
    int fromMinutes = toSeconds(minutes);
    return fromMinutes + seconds;
}

public static int toSeconds(int minutes) {
    return minutes * 60;
}

Follow the unfinished work:

  1. main starts and calls totalSeconds(2, 30). Its assignment to total must wait.
  2. The new frame has minutes = 2 and seconds = 30. It calls toSeconds(minutes) and waits for fromMinutes.
  3. toSeconds gets its own minutes = 2. It returns 120 and its frame is popped.
  4. totalSeconds stores fromMinutes = 120, adds 30, and returns 150. Its frame is popped.
  5. main stores total = 150 and prints 150.

At the deepest point, the frames from bottom to top are main, totalSeconds, and toSeconds. Both helpers have a parameter named minutes, but those parameters occupy different frames. The waiting caller's locals do not become visible to the method above it.

A later call gets a fresh frame. A local counter does not remember its previous value after its call has ended; the return value is what can carry a result back.

Read a stack trace from the error outward

An unhandled exception prints a stack trace that shows where the error happened and which calls led there. Here is a complete file:

public class Main {
    public static void main(String[] args) {
        report(300, 0);
    }

    public static void report(int meters, int minutes) {
        int speed = perMinute(meters, minutes);
        System.out.println(speed + " m per minute");
    }

    public static int perMinute(int meters, int minutes) {
        return meters / minutes;
    }
}

The first output line is Exception in thread "main" java.lang.ArithmeticException: / by zero. The frames beneath it are:

at Main.perMinute(Main.java:12)
at Main.report(Main.java:7)
at Main.main(Main.java:3)

The top frame identifies the integer division by zero. The next two locate the calls that supplied the path to it. The line numbers belong to this exact file layout; adding a line changes them.

The stack has finite space. A chain that keeps adding calls without letting them finish can cause StackOverflowError. A debugger's stack view lets you inspect the same chain while paused at a breakpoint, including each waiting call's separate variables.

Key Takeaways

  • Each call pushes a fresh frame; a return pops that frame and resumes the caller.
  • The newest unfinished call runs first: the stack is last in, first out.
  • Same-named locals in different frames are separate variables.
  • Trace a returned value back into the waiting expression or assignment.
  • Read a stack trace from the error frame at the top toward its callers below.
  • A chain that keeps adding frames can exhaust the stack.
4

Overload methods

One useful operation may accept several kinds of input. Overloading lets those forms share a name while keeping a distinct parameter list for each one. First check whether two declarations really have different signatures. Then follow the compiler's choice at a call: count the arguments, identify their types, and compare the compatible versions. A receiving variable's type cannot rescue a call whose arguments do not identify a suitable overload.

4.1 Write overloaded methods

Overloading gives methods the same name with different parameter lists. It is useful when the methods perform the same job for different numbers or types of input.

Compare signatures

For these methods, a signature consists of the name and the ordered parameter types. The number of parameters follows from that list.

public static int max(int a, int b) {
    if (a > b) {
        return a;
    }
    return b;
}

public static int max(int a, int b, int c) {
    return max(max(a, b), c);
}

public static double max(double a, double b) {
    if (a > b) {
        return a;
    }
    return b;
}

The signatures are max(int, int), max(int, int, int), and max(double, double). max(3, 9) returns 9 using the first. max(3, 9, 5) calls the second: the inner two-int call returns 9, then the outer two-int call compares 9 and 5, also returning 9. max(2.5, 1.0) uses the double version and returns 2.5.

Know which changes do not count

Changing only a return type does not create an overload. These headers conflict:

public static int area(int w, int h)
public static double area(int w, int h)

Both have the signature area(int, int). Java rejects the duplicate declaration. Renaming the parameters to width and height leaves the same signature too: callers supply values by position, not by parameter name.

The order of different types does count. describe(String s, int n) and describe(int n, String s) are distinct signatures. They compile together, but a caller has to remember an easy-to-confuse ordering, so use such a pair only when it helps the design.

Let a shorter overload supply a default

Java does not provide default parameter values in method declarations. A shorter overload can call a longer one with a fixed argument:

public static void printLine(int length, char symbol) {
    for (int i = 0; i < length; i++) {
        System.out.print(symbol);
    }
    System.out.println();
}

public static void printLine(int length) {
    printLine(length, '-');
}

printLine(5, '*'); prints *****. printLine(4); enters the shorter method, which calls the longer one with 4 and '-', printing ----. The loop lives in one place, so changes to the printing task apply to both forms.

Java's library also uses overloads. System.out.println accepts an int, a double, a char, a boolean, or a String through different versions. Math.abs and Math.max offer versions for int, long, float, and double.

Keep one meaning for the shared name. Printing a receipt and printing a label are different jobs; clear names such as printReceipt and printLabel tell the caller which job will happen.

Key Takeaways

  • Overloads share a name and differ in the number, types, or order of parameter types.
  • Return types and parameter names do not distinguish signatures.
  • A shorter overload can call a longer one with a fixed default argument.
  • Use one overloaded name for one job with different input forms.

4.2 Predict which overloaded method runs

The compiler chooses an overload from the argument count and argument types. Work out that choice before considering how the returned value will be used.

Start with exact matches

Suppose a class defines show(int x) and show(double x). show(5) uses the int version because the literal 5 is an int. show(5.0) uses the double version. A whole-number value written as 5.0 is still a double expression.

For a call with several arguments, compare the type in every position. A candidate with the wrong argument count cannot fit.

Allow widening when needed

If only show(double x) exists, show(5) is valid: the int widens to 5.0. The primitive widening paths include:

byte → short → int → long → float → double
char → int → long → float → double

With both show(long x) and show(double x), an int argument chooses long. That is the more specific compatible parameter type: a long can widen to double, while a double cannot widen back to long.

Widening means a permitted numeric conversion; it does not promise that every such conversion preserves every digit. In particular, converting a sufficiently large long to double can round its value. The int-to-double conversion used in the earlier examples preserves all int values exactly.

A char also has a numeric value. With letter(int code) and letter(String text), letter('A') calls the int version with 65. A character does not become a String to match a parameter. Double quotes in "A" would instead make a String argument.

Reject implicit narrowing

With only show(int x), show(5.0) fails. Java does not narrow a double argument just because its value happens to be a whole number. show((int) 5.0) passes an int after an explicit cast.

Likewise, versions of max for two and three ints cannot accept max(1). No candidate has the required number of parameters, so the compiler reports "no suitable method found". Compare the candidate list with the supplied arguments.

Keep overload selection separate from result conversion

Consider int twice(int n) and double twice(double x). In double d = twice(3);, the argument selects the int overload. That call returns 6, then the assignment widens it to 6.0. The destination d does not select the double overload.

Recognize an ambiguous call
public static void combine(int a, double b) { }
public static void combine(double a, int b) { }

combine(1, 2) fits the first after widening its second argument and the second after widening its first. Neither signature is more specific across both positions. Java reports "reference to combine is ambiguous"; it does not choose the definition written first.

combine(1, 2.0) fits only (int, double), because the other signature would need a narrowing conversion of 2.0. A clear argument type or a better set of overloads removes the ambiguity.

Key Takeaways

  • Choose an overload from argument count and types at compile time.
  • An exact match wins; widening can make another version compatible.
  • Java does not implicitly narrow numeric method arguments.
  • The variable receiving the result does not choose the overload.
  • Ambiguity means several versions fit and none is more specific across the call.
5

Divide a program into methods

A program's methods should reveal its plan. Give each method one meaningful job, pass it the values it needs, and let its result feed the next step. Repeated code often reveals a missing method; a long method often reveals several jobs mixed together. Plan the headers first, build small pieces with known results, and connect them gradually. This makes both the data flow and the location of a new bug easier to see.

5.1 Give each method one clear job

Decomposition means dividing a problem into smaller tasks and solving each task in its own method. Choose tasks whose names help someone read the program's plan.

Separate calculation from input and output

A bike-ride program needs a speed calculation and a report. They use the same data but have different jobs:

public static double kilometersPerHour(double km, double hours) {
    return km / hours;
}

public static void printRideReport(double speed) {
    System.out.println("Speed: " + speed + " km/h");
}

For a ride of 150 km in 2 hours, the calculation returns 75.0. The reporting method receives that value and displays it. A caller connects the steps:

double speed = kilometersPerHour(150, 2);
printRideReport(speed);

The calculation reads no keyboard input and prints no report. Another program can use it to compare rides or store speeds without changing its body. To test it, call it with known inputs and compare the returned number with the expected one.

Recognize a method with too many jobs

A name such as readAndCheckAndPrint suggests several actions. Other clues include sections marked by comments, a body longer than one screen, and groups of variables that serve unrelated purposes. These are reasons to inspect the method, not mechanical limits on how many lines it may have.

Split at a meaningful boundary. Input code can obtain a value, a boolean helper can check it, a calculation can return a result, and a reporting method can display it. Then main reads like a short account of how those tasks connect.

Focused methods are easier to read on their own, reuse, and test. If a reporting format changes, edit the reporting method. If a calculation is wrong, test that calculation without needing to type a whole session of input.

Let the header explain the data flow

In kilometersPerHour(double km, double hours), the name states the result, the parameter names state the quantities, and the double return type states the kind of answer. A short Javadoc comment can add the meaning of the inputs and result:

/**
 * Calculates a ride's average speed.
 * @param km distance in kilometers
 * @param hours elapsed time in hours, greater than zero
 * @return speed in kilometers per hour
 */

Place that comment directly above the method header. A useful comment adds information such as units or an input requirement; it need not narrate each line of the body.

A helper needed only by its own class can be private static. private prevents other classes from calling it, while code in the same class can still use it. public static makes the helper available to other classes.

Splitting every obvious statement into its own wrapper can also obscure the plan. Keep a method when its name stands for a meaningful step or reusable calculation. A chain of helpers that merely pass the same call along adds more places to inspect without explaining more of the task.

Key Takeaways

  • Decompose a program into meaningful tasks with clear names.
  • Calculation methods take parameters and return results; reporting methods display them.
  • Focused helpers can be reused and tested separately.
  • A header and a short Javadoc comment can state inputs, units, and result.
  • Use private static for helpers that only their own class should call.
  • Split where a name clarifies the task, not at every individual statement.

5.2 Replace repeated code with a parameterized method

Duplicate code repeats the same job in more than one place. When only the input values differ, one parameterized method can keep the shared work together.

Find the shared calculation

Suppose a program sums from 1 to 10, then from 1 to 50:

int total1 = 0;
for (int i = 1; i <= 10; i++) {
    total1 += i;
}
System.out.println("Sum 1 to 10: " + total1);
int total2 = 0;
for (int i = 1; i <= 50; i++) {
    total2 += i;
}
System.out.println("Sum 1 to 50: " + total2);

Both loops start at 1, add into a total, and stop at an upper limit. Only that limit changes. A parameter n can carry it into a shared calculation.

Extract the method
public static int sumUpTo(int n) {
    int total = 0;
    for (int i = 1; i <= n; i++) {
        total += i;
    }
    return total;
}

n is the varying input. total and i are working variables that belong inside the helper. The caller needs the finished sum, so the helper returns an int.

Replace both repeated sections:

System.out.println("Sum 1 to 10: " + sumUpTo(10));
System.out.println("Sum 1 to 50: " + sumUpTo(50));

sumUpTo(10) returns 55, and sumUpTo(50) returns 1275. The printed lines are "Sum 1 to 10: 55" and "Sum 1 to 50: 1275", as before. The descriptions remain in the caller; the loop performs only the calculation.

Check the extraction in a fixed order
  1. Mark the statements doing the repeated job.
  2. Identify every value that differs between the copies.
  3. Make those values parameters with suitable types, and return any result needed outside.
  4. Replace every copy with a call using its original inputs.
  5. Run the same inputs before and after, and compare the behavior.

Changing code's structure while preserving its behavior is refactoring. Leaving one original copy behind means a later fix still has two places to update. Moving a print into a loop or changing a loop endpoint is a behavior change, even when the code is now shorter.

When two differences have different types, use matching parameters. Repeating different text different numbers of times suggests printRepeated(String text, int times); the word is a String and the count is an int.

Similar-looking code does not always do the same job. A boolean parameter that switches a method between unrelated calculations can make its calls hard to interpret. Give distinct jobs distinct names. Extract the repeated operation only when varying its inputs preserves one clear meaning.

Key Takeaways

  • Identify the shared job and make its changing inputs parameters.
  • Keep working variables local and return any result the caller needs.
  • Refactor every copy and compare behavior with the same inputs.
  • Merge copies of the same job, not unrelated jobs that only look similar.

5.3 Design a program top-down and test it method by method

Top-down design starts with the whole task and refines it into smaller method calls. Decide what each call needs and returns before filling in every detail.

Plan the steps and headers

A weekly exercise program reads 7 daily durations, totals them, and prints a report. Its helpers can be planned as:

  • readMinutes(Scanner scanner, int day) returns one valid day's minutes.
  • isValidMinutes(int minutes) answers whether the input is from 0 to 1440.
  • formatDuration(int minutes) returns text with whole hours and remaining minutes.
  • averagePerDay(int total, int days) returns a double average.
  • printSummary(int totalMinutes, int days) prints the report.

The same Scanner is passed to every input call. A helper such as isValidMinutes has no need to read input itself.

Use stubs while building

A stub has its final header but a temporary minimal body, such as return 0;. It lets the program compile before a helper is implemented. Replace one stub, compile, and check that method before replacing the next. A compiling stub is still unfinished work; its fixed answer cannot verify a real calculation.

Here is the completed program:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int total = 0;
        for (int day = 1; day <= 7; day++) {
            total += readMinutes(scanner, day);
        }
        printSummary(total, 7);
    }

    public static int readMinutes(Scanner scanner, int day) {
        System.out.println("Minutes for day " + day + ":");
        int minutes = scanner.nextInt();
        while (!isValidMinutes(minutes)) {
            System.out.println("Enter minutes from 0 to 1440:");
            minutes = scanner.nextInt();
        }
        return minutes;
    }

    public static boolean isValidMinutes(int minutes) {
        return minutes >= 0 && minutes <= 1440;
    }

    public static String formatDuration(int minutes) {
        return minutes / 60 + " h " + minutes % 60 + " min";
    }

    public static double averagePerDay(int total, int days) {
        return (double) total / days;
    }

    public static void printSummary(int totalMinutes, int days) {
        System.out.println("Total: " + formatDuration(totalMinutes));
        System.out.println("Daily average: "
            + averagePerDay(totalMinutes, days) + " min");
        if (totalMinutes >= 150) {
            System.out.println("Weekly goal reached");
        }
    }
}

For integer input, readMinutes repeats its range check until the number is valid. With daily inputs 30, 45, 0, 60, 90, 45, and 45, the total is 315. Formatting gives "5 h 15 min", the average is 45.0 minutes, and the program reports that its weekly goal of 150 minutes is reached.

Check small methods and their boundaries

Call each calculation with known results. formatDuration(0) should give "0 h 0 min", 59 gives "0 h 59 min", 60 gives "1 h 0 min", and 135 gives "2 h 15 min". The inputs just below and at 60 check the change from minutes to a whole hour.

For isValidMinutes, test -1, 0, 1440, and 1441. The expected results are false, true, true, and false. Printing expected and actual values side by side makes an error visible. JUnit automates this style of check.

Bottom-up development starts by writing and testing small helpers, then joins them into larger steps. You can plan top-down and build bottom-up: settle the data flow first, prove the small calculations work, then check the connected program.

Key Takeaways

  • Top-down design turns a whole task into calls, then refines each task.
  • Decide each helper's inputs and return type before its body.
  • A stub preserves a planned header while its body is still temporary.
  • Test known results and values at or around boundaries.
  • Build and check one method at a time, then test the connected program.
  • Bottom-up development builds small helpers before combining them.

Java Methods examples

5 Walkthroughs

1

Build a reusable line printer

11 steps
Define a helper, trace its calls, and add parameters for changing inputs.
  1. 1
    IntroductionTurn a repeated action into a call

    A report needs a short separator in several places. Giving that action a method name lets the report ask for a separator without repeating the printing statements. That named action is a method, and one definition serves every call.

    Start with a fixed separator. Then let the caller choose its width and symbol with parameters. Follow the definition, the call, and the supplied values as three different parts of the job.

  2. 2
    ExplanationRead a method header
    public static void printDivider() {
        System.out.println("====");
    }
    

    printDivider is the name. public allows calls from other classes; static means no object is needed. void says no value comes back, and () says no input is required.

    The statement inside the braces is the body. Nothing prints merely because this definition exists.

  3. 3
    TipPut the helper beside main

    In a classic class, main and printDivider are separate methods inside the same class braces. Close the body of main before starting the helper's header.

    A helper may appear above or below main; its position does not schedule it. A definition placed inside main is rejected. Check the braces first when a method header produces "illegal start of expression".

  4. 4
    ExampleFollow the first call

    Suppose main contains:

    System.out.println("Items");
    printDivider();
    System.out.println("End");
    

    Execution first prints "Items". The call enters printDivider, which prints "====". When the helper finishes, main continues at its next statement and prints "End".

    The helper's body runs between the two caller statements, exactly where the call appears.

  5. 5
    ChallengePlace a second separator

    main calls printDivider();, prints "A", and calls printDivider(); again. What three lines appear?

    ---reveal---

    The lines are "====", "A", and "====". Each call enters the same helper body, prints once, and returns to its own place in main.

    Writing printDivider; would not make a call. Even without arguments, the parentheses are required.

  6. 6
    ExplanationLet the width be an input

    Replace the fixed body with a loop:

    public static void printDivider(int length) {
        for (int i = 0; i < length; i++) {
            System.out.print("=");
        }
        System.out.println();
    }
    

    length is a parameter declared in the header. In printDivider(6);, the argument 6 becomes its starting value. Six loop passes print six symbols before the line ends.

  7. 7
    ExampleEvaluate an expression before the call
    int sections = 3;
    printDivider(sections + 2);
    

    First, evaluate sections + 2 to get 5. Then enter the helper with its parameter length = 5. Its loop prints "=====".

    sections and length need not have the same name. A parameter receives the evaluated argument value; the caller does not put the type in the call.

  8. 8
    ExampleAdd a second changing input

    To choose the symbol too, use:

    public static void printDivider(int length, char symbol) {
        for (int i = 0; i < length; i++) {
            System.out.print(symbol);
        }
        System.out.println();
    }
    

    The call printDivider(3, '+'); passes 3 to length and '+' to symbol, printing "+++". Each parameter needs its own type in the header.

  9. 9
    TipCheck count, order, and type

    A call must supply a compatible value for each parameter. printDivider(3); is now missing the symbol, while printDivider("3", '+'); supplies text where an int is needed.

    Java can widen an int to double for a double parameter. It cannot implicitly narrow 3.7 to fit this int parameter. The explicit cast (int) 3.7 supplies 3 by dropping the fractional part.

  10. 10
    ChallengePredict a parameterized call

    Using the two-parameter helper, what line does this print?

    int width = 4;
    printDivider(width - 1, '#');
    

    ---reveal---

    It prints "###". The expression is evaluated to 3, then the first parameter receives that count and the second receives '#'. The loop runs three times.

    The call is a statement, so it ends with a semicolon. Its argument expressions contain values, not parameter declarations.

  11. 11
    RecapRead the action and its inputs

    A definition gives a task a header and body; a call runs it and then resumes the caller. Keep definitions inside the class and outside other methods.

    Parameters describe the needed inputs. Calls supply evaluated arguments in the matching order, with the correct count and compatible types.

2

Return answers and finish searches

13 steps
Use return values in callers, then trace early returns and complete return paths.

Save this lesson to follow every Walkthrough step by step.

  1. 1
    IntroductionGive a result back to the caller
  2. 2
    ExplanationMake a call stand for a value
  3. 3
    Key InsightPrinting cannot fill an assignment
  4. 4
    ExampleKeep the fractional part
  5. 5
    ChallengeUse the result in another expression
  6. 6
    ExampleReturn formatted text
  7. 7
    ExplanationA return ends this call
  8. 8
    TipCheck the route that misses the if
  9. 9
    ExampleWrite a search with a failure result
  10. 10
    ExampleTrace the search until it ends
  11. 11
    ChallengeFind a premature failure
  12. 12
    ChallengeConnect a search result to a condition
  13. 13
    RecapTrack both the answer and the stopping point
3

Keep each call's variables separate

15 steps
Trace scope, copied values, and waiting stack frames through a small program.

Save this lesson to follow every Walkthrough step by step.

  1. 1
    IntroductionName each variable by its call
  2. 2
    ExplanationA helper sees its own locals
  3. 3
    ExampleKeep a total outside the loop
  4. 4
    ChallengeSeparate scope from initialization
  5. 5
    ExampleCopy a number into a parameter
  6. 6
    ExampleAssign the returned replacement
  7. 7
    ChallengePredict a second call
  8. 8
    ConnectionCopied references follow the same rule
  9. 9
    ExampleStart an outer calculation
  10. 10
    ExamplePause the caller and push another frame
  11. 11
    ExampleCarry results back down the stack
  12. 12
    TipRead an error from the top frame
  13. 13
    ChallengeFind the waiting work
  14. 14
    ChallengeConnect copies with stack results
  15. 15
    RecapKeep names, values, and frames distinct
4

Choose the right overloaded method

12 steps
Compare signatures, reuse a longer overload, and resolve calls from argument types.

Save this lesson to follow every Walkthrough step by step.

  1. 1
    IntroductionOne job, several input forms
  2. 2
    ExplanationIdentify a signature
  3. 3
    Key InsightA return type cannot create an overload
  4. 4
    ExampleDelegate to the full version
  5. 5
    ChallengeCheck a proposed third declaration
  6. 6
    ExplanationChoose an exact numeric match
  7. 7
    ExampleUse widening without narrowing
  8. 8
    ExampleSeparate the call from its assignment
  9. 9
    ExampleCompare every argument position
  10. 10
    TipUse the candidate list to diagnose a call
  11. 11
    ChallengeChoose a version and then use its result
  12. 12
    RecapCheck definitions before calls
5

Build a small report from tested helpers

16 steps
Separate jobs, extract repeated code, and plan a complete program around tested methods.

Save this lesson to follow every Walkthrough step by step.

  1. 1
    IntroductionTurn a report into small jobs
  2. 2
    ExplanationName the job before writing the body
  3. 3
    ExampleMake the calculation reusable
  4. 4
    ExampleGive output its own method
  5. 5
    ChallengeReuse a calculation without a report
  6. 6
    ExplanationFind what repeated code changes
  7. 7
    ExampleChoose the extracted header
  8. 8
    ExamplePut the shared loop in one place
  9. 9
    ChallengePreserve the last repetition
  10. 10
    ExplanationPlan the program from the top
  11. 11
    TipUse a stub only while building
  12. 12
    ExamplePass the same input reader
  13. 13
    ExampleCheck the calculation before connecting it
  14. 14
    ExampleCheck a connected input sequence
  15. 15
    ChallengeLocate a connection error
  16. 16
    RecapBuild meaningful pieces and connect them

Java Methods practice questions

40 Practice Questions in 4 sets

Set 1: Calls, values, and small program steps10 Practice Questions

Question 1 of 10

What line does this call print?

public static void showPair(int rows, int columns) {
    System.out.println(rows + ":" + columns);
}
int width = 7;
showPair(3, width - 2);
  1. 5:3
  2. 3:7
  3. 7:3
  4. 3:5
Show answerHide answer
Answer: D
The first argument supplies rows = 3. The expression width - 2 is evaluated before the call, so the second parameter receives 5 and the output is "3:5". The caller's name width does not change the positional matching of arguments.

Question 2 of 10

What value does halfTotal(8, 5) return?

public static double halfTotal(int a, int b) {
    return (a + b) / 2;
}
  1. 6.0
  2. 6.5
  3. 13.0
  4. 7.0
Show answerHide answer
Answer: A
The addition produces the int 13, and dividing by the int 2 produces 6. That result widens to the returned double 6.0. A double return type does not make the earlier division use decimals; a divisor of 2.0 would be needed to obtain 6.5.

Question 3 of 10

A classic Java class has a main method and needs a new printMenu method. Where should the new definition go?
  1. Inside main, after its last statement.
  2. Inside the class, outside all other methods.
  3. Outside the class, after its closing brace.
  4. Inside the method that needs to call it.
Show answerHide answer
Answer: B
A method definition belongs inside the class and outside every other method. Calling a helper from main does not make its definition part of main; placing it there would create a nested method definition, which Java rejects.

Question 4 of 10

Why does this method fail to compile?

public static String label(int n) {
    if (n >= 0) {
        return "ready";
    }
}
  1. The return value must be printed first.
  2. The comparison cannot appear in a method.
  3. Negative inputs reach the end without a value.
  4. String methods cannot return inside an if.
Show answerHide answer
Answer: C
A negative input skips the if body and reaches the closing brace with no String result. A method with this return type needs a return for that route too. Returning from inside an if is valid; the missing answer outside that branch causes the error.

Question 5 of 10

A loop must add the integers 2 through 4 and print the total afterward. What declaration should replace the comment?

// declaration here
for (int i = 2; i <= 4; i++) {
    total += i;
}
System.out.println(total);
  1. int total;
  2. int total = 0;
  3. int total = 2;
  4. int total = i;
Show answerHide answer
Answer: B
Initialize total to 0 before the loop so all three additions update the same variable and it remains visible to the final print. Declaring int total; alone does not assign a starting value, so total += i would read an uninitialized local.

Question 6 of 10

What two numbers are printed, in order?

public static void lower(int level) {
    level -= 3;
    System.out.println(level);
}
int level = 14;
lower(level);
System.out.println(level);
  1. 11, then 14
  2. 11, then 11
  3. 14, then 11
  4. 14, then 14
Show answerHide answer
Answer: A
The helper receives its own level initialized to 14, lowers that copy to 11, and prints it. The caller's level stays 14 and is printed next. Using the same name in both methods does not make parameter assignment update the caller's variable.

Question 7 of 10

A class already declares public static int scale(int value). What additional header would conflict with its signature?
  1. public static int scale(int value, int factor)
  2. public static double scale(double value)
  3. public static long scale(long value)
  4. public static double scale(int amount)
Show answerHide answer
Answer: D
The extra header with an int parameter still has the signature scale(int). Its double return type and changed parameter name do not distinguish it from the existing method. Changing the parameter type or adding a parameter would create a different signature.

Question 8 of 10

A class has show(int n) and show(double n). Which method runs for show(12.0)?
  1. show(int), with 12
  2. Both, with 12.0
  3. show(double), with 12.0
  4. Neither; the call is ambiguous
Show answerHide answer
Answer: C
The literal 12.0 has type double, so the double overload is an exact match. Its whole-number value does not make the expression an int. The int overload would require a narrowing conversion, which Java does not perform implicitly for this argument.

Question 9 of 10

A route program needs to calculate an average speed and display a report. What split makes the speed calculation reusable in a program that compares routes?
  1. Calculate and return speed; print it in a separate method.
  2. Calculate and print speed; return no value from the method.
  3. Read and print speed; calculate it again in every caller.
  4. Calculate and print speed; return the report's heading.
Show answerHide answer
Answer: A
A method that receives distance and time and returns speed can serve either a report or a comparison. Keep the display in another method. A void calculation that only prints its answer leaves the comparison code without a numeric result it can use.

Question 10 of 10

A program should accept task durations from 0 through 90 minutes and report their average. It currently uses these helpers. What two input calls can expose both independent defects?

public static boolean valid(int m) {
    return m > 0 && m <= 90;
}
public static double mean(int total, int count) {
    return total / count;
}
  1. valid(45) and mean(8, 2)
  2. valid(0) and mean(7, 2)
  3. valid(91) and mean(8, 2)
  4. valid(90) and mean(7, 2)
Show answerHide answer
Answer: B
valid(0) wrongly returns false even though zero is allowed. mean(7, 2) returns 3.0 instead of 3.5 because integer division occurs before widening. Testing valid(90) and that mean catches only the division defect, since the upper endpoint already works.
Set 2: Trace helpers and repair method boundaries10 Practice Questions

Save this lesson to see every answer and practice every set.

Question 1 of 10

What sequence of lines is printed?

public static void frame() {
    System.out.println("Open");
    mark();
    System.out.println("Close");
}
public static void mark() {
    System.out.println("Mark");
}

main calls frame(); and then prints "Done".

  1. "Open", "Close", "Mark", "Done"
  2. "Mark", "Open", "Close", "Done"
  3. "Open", "Mark", "Done", "Close"
  4. "Open", "Mark", "Close", "Done"
Show answerHide answer

Save this lesson to see this answer.

Question 2 of 10

A method has the header public static void repeat(int count). What value reaches count in repeat((int) 3.9 + 2);?
  1. 3
  2. 5
  3. 6
  4. 5.9
Show answerHide answer

Save this lesson to see this answer.

Question 3 of 10

What value is assigned to result?

public static int addTwo(int n) {
    return n + 2;
}
public static int product(int a, int b) {
    return a * b;
}
int result = product(addTwo(4), addTwo(addTwo(1)));
  1. 24
  2. 42
  3. 30
  4. 18
Show answerHide answer

Save this lesson to see this answer.

Question 4 of 10

The method should return the first even value in an inclusive range, or -1 if none exists. It wrongly returns -1 for (9, 12). What change fixes the search?

public static int firstEven(int start, int end) {
    for (int n = start; n <= end; n++) {
        if (n % 2 == 0) {
            return n;
        } else {
            return -1;
        }
    }
    return -1;
}
  1. Remove the else branch and keep the final return.
  2. Replace the else return with return n + 1;.
  3. Move the final return into the loop after the if/else.
  4. Change the if test to n % 2 != 0.
Show answerHide answer

Save this lesson to see this answer.

Question 5 of 10

A helper needs the number held in main's local variable pages. How should the data reach the helper?
  1. Declare another uninitialized pages in the helper.
  2. Move the helper below main in the class.
  3. Keep the helper call inside pages' scope only.
  4. Add a parameter and pass pages as an argument.
Show answerHide answer

Save this lesson to see this answer.

Question 6 of 10

What value returns to main from outer(4)?

public static int outer(int n) {
    int saved = n;
    int changed = inner(n + 1);
    return saved + changed;
}
public static int inner(int n) {
    n *= 2;
    return n - 1;
}
  1. 14
  2. 13
  3. 19
  4. 9
Show answerHide answer

Save this lesson to see this answer.

Question 7 of 10

A two-argument printBorder(int length, char symbol) already contains the printing loop. How should printBorder(int length) supply a default '#' without duplicating the loop?
  1. Call printBorder(length, '#'); in its body.
  2. Add char symbol = '#' as a default header parameter.
  3. Call printBorder('#', length); in its body.
  4. Call printBorder(length); in its body.
Show answerHide answer

Save this lesson to see this answer.

Question 8 of 10

These overloads share a class. What value is stored in answer?

public static int adjust(int n) { return n + 1; }
public static double adjust(double n) { return n + 0.5; }
double answer = adjust(6);
  1. 6.5
  2. 6.0
  3. 7.5
  4. 7.0
Show answerHide answer

Save this lesson to see this answer.

Question 9 of 10

Two code blocks calculate rectangle areas, one using 8 * 3 and one using 11 * 4. Both results are needed for later comparisons. What helper header fits an extraction of this shared calculation?
  1. public static void area(int width, int height)
  2. public static int area(int width)
  3. public static int area(int width, int height)
  4. public static int area()
Show answerHide answer

Save this lesson to see this answer.

Question 10 of 10

What makes public static int countItems(int limit) { return 0; } a useful temporary stub?
  1. It proves that all item counts are correct.
  2. It removes the need to test the completed method.
  3. It lets calls compile before the real body is ready.
  4. It supplies Java with a default parameter value.
Show answerHide answer

Save this lesson to see this answer.

Set 3: Connect arguments, return paths, and design10 Practice Questions

Save this lesson to see every answer and practice every set.

Question 1 of 10

A programmer writes this inside a class. Why is the helper definition rejected?

public static void main(String[] args) {
    public static void printTitle() {
        System.out.println("Schedule");
    }
}
  1. A helper must be placed above main.
  2. A printing helper must return a String.
  3. The helper is defined inside another method.
  4. The helper name must start with uppercase.
Show answerHide answer

Save this lesson to see this answer.

Question 2 of 10

The method returns the number of whole groups. What does groups(5, 18) return?

public static int groups(int groupSize, int items) {
    return items / groupSize;
}
  1. 3
  2. 0
  3. 3.6
  4. 4
Show answerHide answer

Save this lesson to see this answer.

Question 3 of 10

A calendar helper is written as below. What pair of returned results comes from leap(2100) and then leap(2400)?

public static boolean leap(int year) {
    return (year % 4 == 0 && year % 100 != 0)
        || year % 400 == 0;
}
  1. true, then true
  2. false, then true
  3. false, then false
  4. true, then false
Show answerHide answer

Save this lesson to see this answer.

Question 4 of 10

What text is printed by the caller?

public static void tag(String name) {
    name = name + "-checked";
}
String label = "parcel";
tag(label);
System.out.println(label);
  1. "parcel-checked"
  2. "checked"
  3. "parcelparcel"
  4. "parcel"
Show answerHide answer

Save this lesson to see this answer.

Question 5 of 10

An error report begins with ArithmeticException: / by zero and these frames. Where did the failing division occur?

at Main.unitCount(Main.java:23)
at Main.printLoad(Main.java:15)
at Main.main(Main.java:5)
  1. In main, at line 5.
  2. In printLoad, at line 15.
  3. In unitCount, at line 23.
  4. After unitCount returned to line 15.
Show answerHide answer

Save this lesson to see this answer.

Question 6 of 10

A class declares public static void describe(String name, int count). What header adds a valid overload by changing the order of parameter types?
  1. public static int describe(String name, int count)
  2. public static void describe(int count, String name)
  3. public static void describe(String title, int number)
  4. private static void describe(String name, int count)
Show answerHide answer

Save this lesson to see this answer.

Question 7 of 10

What line is printed by this call? The character 'B' has numeric value 66.

public static int code(int n) { return n + 1; }
public static String code(String s) { return s + "!"; }
double result = code('B');
System.out.println(result);
  1. 67.0
  2. 66.0
  3. "B!"
  4. 67
Show answerHide answer

Save this lesson to see this answer.

Question 8 of 10

A helper should be callable only by code within the same class. What access modifier should its static header use?
  1. public
  2. static
  3. void
  4. private
Show answerHide answer

Save this lesson to see this answer.

Question 9 of 10

The original program prints totals 20 and 30, in that order. After extraction, it uses this helper. How should the two calls be written to preserve those totals?

public static int sumMultiples(int factor, int count) {
    int total = 0;
    for (int i = 1; i <= count; i++) {
        total += factor * i;
    }
    return total;
}

The original first loop added 2, 4, 6, and 8. The second added 5, 10, and 15.

  1. sumMultiples(2, 4) then sumMultiples(5, 3)
  2. sumMultiples(4, 2) then sumMultiples(3, 5)
  3. sumMultiples(2, 8) then sumMultiples(5, 15)
  4. sumMultiples(2, 3) then sumMultiples(5, 2)
Show answerHide answer

Save this lesson to see this answer.

Question 10 of 10

A program reads five daily counts, totals them, and prints an average. The planned helper headers are below. What connection in main lets the reporting step receive all the required data?

public static int readCount(Scanner scanner, int day)
public static double average(int total, int days)
public static void printReport(int total, int days)

The Scanner is already created.

  1. Overwrite one count in the loop; call printReport(count, 5).
  2. Accumulate the five returned counts; call printReport(total, 5).
  3. Print each returned count; call printReport(0, 5) afterward.
  4. Add the day numbers in the loop; call printReport(total, 5).
Show answerHide answer

Save this lesson to see this answer.

Set 4: Diagnose complete method interactions10 Practice Questions

Save this lesson to see every answer and practice every set.

Question 1 of 10

What line is printed?

public static int next(int n) { return n + 1; }
public static double half(int n) { return n / 2.0; }
int n = 5;
next(n);
double result = half(next(n)) + n;
System.out.println(result);
  1. 9.5
  2. 7.5
  3. 3.0
  4. 8.0
Show answerHide answer

Save this lesson to see this answer.

Question 2 of 10

What value does locate(5) return?

public static int locate(int limit) {
    int total = 0;
    for (int n = 1; n <= limit; n++) {
        total += n;
        if (total > 8) {
            return n;
        }
    }
    return -1;
}
  1. 4
  2. 5
  3. 10
  4. 15
Show answerHide answer

Save this lesson to see this answer.

Question 3 of 10

The code must total the weights and print their sum after the loop. It currently fails to compile. What change both fixes the scope problem and preserves a running total?

for (int box = 1; box <= 3; box++) {
    int total = 0;
    total += box * 2;
}
System.out.println(total);
  1. Move only println(total) into the loop.
  2. Declare int total; before the loop and remove its inner declaration.
  3. Move int total = 0; before the loop and remove its inner declaration.
  4. Declare int total = 0; after the loop, before printing.
Show answerHide answer

Save this lesson to see this answer.

Question 4 of 10

What pair of values is printed as a:b?

public static int shift(int n) {
    n += 4;
    return n;
}
int a = 2;
int b = shift(a);
a = shift(b);
System.out.println(a + ":" + b);
  1. 6:10
  2. 10:6
  3. 10:10
  4. 6:6
Show answerHide answer

Save this lesson to see this answer.

Question 5 of 10

At the marked point, what are the values of the two local variables named saved, reading the outer frame first and then the inner frame?

public static int outer(int n) {
    int saved = n + 2;
    return inner(saved) + saved;
}
public static int inner(int n) {
    int saved = n * 3;
    // program pauses here
    return saved;
}

main has called outer(5).

  1. 7 and 21
  2. 21 and 21
  3. 5 and 15
  4. 7 and 7
Show answerHide answer

Save this lesson to see this answer.

Question 6 of 10

A program keeps starting more calls without letting the existing calls finish. Which error can result when no stack space remains?
  1. ArithmeticException
  2. "missing return statement"
  3. "cannot find symbol"
  4. StackOverflowError
Show answerHide answer

Save this lesson to see this answer.

Question 7 of 10

The methods below are declared in one class. What happens at double result = merge(4, 9);?

public static int merge(int a, double b) { return a; }
public static double merge(double a, int b) { return b; }
public static double merge(double a, double b) { return a + b; }
  1. The double destination selects (double, int) and stores 9.0.
  2. The call is ambiguous between the two mixed-type versions.
  3. The int first argument selects (int, double) and stores 4.0.
  4. The all-double version is selected and stores 13.0.
Show answerHide answer

Save this lesson to see this answer.

Question 8 of 10

A sensor calculation is useful, but its current method also prints a long status message. A second caller needs the number without that message. What design lets both callers share one calculation method and choose their own output?
  1. Add a second copy of the calculation without the print.
  2. Rename the existing method to describe both actions.
  3. Return the number and move printing into the reporting caller.
  4. Make the combined method public so both callers can use it.
Show answerHide answer

Save this lesson to see this answer.

Question 9 of 10

Two blocks print a label followed by one line per item. The first prints "Crate" with items numbered 1 through 2; the second prints "Bag" with items numbered 1 through 4. What extracted body preserves that format for printItems(String label, int count)?
  1. Print label inside a loop from 0 while i < count; print no numbers.
  2. Print label once; loop from 1 while i < count and print i.
  3. Print label once; loop from 0 while i <= count and print i.
  4. Print label once; loop from 1 while i <= count and print i.
Show answerHide answer

Save this lesson to see this answer.

Question 10 of 10

A helper should return a decimal daily average:

public static double dailyAverage(int total, int days) {
    return total / days;
}

Why does checking only (24, 6) fail to expose its arithmetic defect?

  1. That division is exact, so truncation loses no fractional part.
  2. The method widens both int operands before doing the division.
  3. That input tests a quotient with a nonzero fractional part.
  4. The result is rounded to the nearest whole number afterward.
Show answerHide answer

Save this lesson to see this answer.

Stuck on your own question? Homework Help

Key Terms

51 Key Terms, each with its definition

A

Accumulator
An accumulator is a variable that keeps a running result as a loop combines successive values into that result.
Declare sum before a loop so each iteration adds to the total kept from the previous pass.
Ambiguous call
An ambiguous call fits several overloads but has no single most specific match, so the compiler cannot select one.
The pairs (int, double) and (double, int) make a call with two int arguments ambiguous.
Argument
An argument is an expression supplied in a method call whose evaluated value is passed to a matching parameter.
In printRepeated("go", 4), the arguments supply the text and the number of repetitions.

B

Block
A block is a group of statements enclosed by braces that can form a method body, loop body, or conditional branch.
Declaring a counter inside an if block keeps that local name within the block's closing brace.
Boolean method
A boolean method returns true or false, often to answer a question that the caller uses directly as a condition.
A call such as isEven(count) can be placed directly inside the parentheses of an if statement.
Bottom-up development
Bottom-up development builds and tests small methods first, then combines them into the larger steps of the program.
Test a validity check and a formatter separately before using them in a complete reporting program.
Boundary case
A boundary case tests an input at or beside a limit where a method's expected behavior changes, helping reveal endpoint errors.
For a valid range from 0 to 1440, check -1, 0, 1440, and 1441 as separate inputs.

C

Call stack
The call stack records unfinished method calls, with the newest call running on top while its callers wait below it.
When main calls a helper that calls another helper, three frames can be on the stack at once.
Cast
A cast is an explicit type conversion written with a target type in parentheses before the expression to convert.
The expression (int) 4.9 supplies 4 to an int parameter by dropping the fractional part.

D

Decomposition
Decomposition divides a program's problem into smaller meaningful tasks that can each be implemented as a focused method.
A ride report can separate obtaining inputs, calculating a speed, and displaying the result.
Delegating overload
A delegating overload calls another version of the same operation, often supplying a fixed value for an omitted argument.
A one-argument line printer can call the two-argument version with a fixed dash character.
Duplicate code
Duplicate code repeats the same or nearly the same statements, leaving several places to update when the shared job changes.
Two sum loops with different upper limits can often be replaced by one helper and two calls.

E

Early return
An early return ends a method before the end of its body, often after a match is found or an input condition is handled.
A search stops as soon as return candidate; executes, even if the loop has more candidates.
Exact match
An exact match occurs when the argument types already match a method's parameter types without a conversion.
With show(int) and show(double), show(9) has an exact match with the int version.

H

Helper method
A helper method performs a smaller task used by another method, making the larger operation easier to read and build.
A report method can call a duration formatter instead of performing the formatting itself.

I

Immutable String
An immutable String is a String whose contents cannot change after creation; text operations can produce a different String.
Concatenating "!" and assigning the result to a String parameter leaves the caller's reference unchanged.
Incremental development
Incremental development adds and checks a small piece of working code at a time, keeping the cause of a new error easier to find.
Implement one helper, compile it, test known results, and then connect it to the next part.
Initialization
Initialization gives a variable its starting value before later code reads or updates it; locals have no automatic starting value.
Writing int total = 0; before a sum loop gives the first addition an existing total to update.

J

Javadoc
Javadoc is documentation written in a /** ... */ comment above a declaration, with tags describing parameters and results.
Use @param minutes to explain an input and @return to describe the formatted text it produces.

L

Last in, first out
Last in, first out is the stack order in which the newest unfinished call completes before its waiting caller resumes.
An inner helper returns before the outer helper can finish using that returned value.
Local variable
A local variable is declared inside a method or block and belongs to the execution of that region, not to the whole program.
The local total in a helper is separate from another method's local variable also named total.

M

Method
A method is a named block of statements that performs a task and runs whenever program execution reaches a call to it.
A printHeader() method can print the same report heading at several places in a program.
Method body
A method body is the block enclosed by braces that contains the statements executed when the method is called.
The call enters the body, executes its statements, and then continues in the waiting caller.
Method call
A method call is an expression that names a method and supplies its arguments in parentheses to invoke its body.
The statement printHeader(); runs the header-printing method at that point in the caller.
Method extraction
Method extraction moves a coherent piece of code into a helper, turning changing inputs into parameters and needed results into returns.
Extracting a summing loop into sumUpTo(int n) leaves the caller responsible for its own report text.
Method header
A method header declares a method's name, modifiers, return type, and parameters before the body begins.
The header public static void greet() describes a callable action with no input and no returned value.
Method signature
A method signature for these methods is its name and ordered parameter types; return types and parameter names do not distinguish it.
Changing width to w leaves area(int, int) unchanged and cannot create a new overload.

N

Narrowing conversion
A narrowing conversion changes a numeric value to a restricted type and may lose information; method calls do not do it implicitly.
Passing 9.0 to an int parameter fails without a cast, even though the value has no fractional part.
Nested call
A nested call is a method call used within another call, so its result must be obtained before the outer method runs.
In Math.max(sum(2, 6), 5), the result 8 becomes the first argument of Math.max.

O

Overload resolution
Overload resolution is the compiler's process of selecting a suitable method version from a call's argument count and types.
An int argument chooses an exact int overload before a version that would need conversion.
Overloading
Overloading defines methods with the same name and different parameter lists so one operation accepts different input forms.
Two methods named max can accept two ints and three ints while keeping one meaning for the name.

P

Parameter
A parameter is a typed variable declared in a method header that receives a value when a particular call begins.
In printRepeated(String text, int times), text and times are the two declared parameters.
Parameter list
A parameter list is the ordered sequence of typed input variables between the parentheses of a method header.
The list (int width, int height) requires two arguments, matched first to width and then to height.
Pass by value
Pass by value means each parameter receives a copy of its argument's value, so reassigning the parameter leaves the caller's variable alone.
A helper can increase its int parameter while the caller's original int remains unchanged.
Private method
A private method can be called only by code in its own class, keeping an internal helper unavailable to other classes.
Declaring a calculation private static allows its own class to use it without offering an external call.

R

Refactoring
Refactoring changes the structure of code while preserving its behavior, such as replacing repeated calculations with calls.
Compare the same inputs before and after extraction to check that both results and output stay the same.
Reference
A reference is a value that points to an object; copying that value can let two variables refer to the same object.
Passing a String copies its reference into the parameter without linking the two variables' assignments.
Return statement
A return statement ends the current method call, carrying a value back for a non-void method or no value for a void method.
The statement return minutes * 60; finishes the calculation and supplies the number of seconds.
Return type
A return type specifies the type of value a method supplies to its caller; void declares that it supplies no value.
A method declared double average(int a, int b) promises a double result to its caller.
Return value
A return value is the result a method sends back to the call site, where it can be stored or used in another expression.
After int total = sum(6, 8);, the returned 14 is stored in the caller's variable total.

S

Scope
The scope of a variable is the region of program text where its name can legally be used to refer to that variable.
A counter declared in a for header is in scope in that loop, but cannot be read after it.
Sentinel value
A sentinel value is a special agreed result used to signal a condition such as a search finding no matching candidate.
Returning -1 after a search can signal "not found" when -1 cannot be a valid match.
Stack frame
A stack frame holds one call's parameters, local variables, and information about where its caller must continue afterward.
Two calls can each have a parameter named minutes because the parameters occupy separate frames.
Stack overflow
A stack overflow occurs when a chain of method calls needs more stack space than is available, producing StackOverflowError.
Calls that keep adding frames without letting them finish can eventually exhaust the stack.
Stack trace
A stack trace is a printed list of active call frames at an error, showing method names and locations in the calling chain.
The first frame locates the failure, and the lines below it show which methods called into it.
Static method
A static method belongs to a class and can be called without creating an object of that class.
The static call Math.abs(-6) uses the class name Math and returns the positive value 6.
Stub
A stub is a temporary method with its planned header and a minimal body that allows unfinished surrounding code to compile.
A temporary return 0; can stand in while the real calculation is being implemented and checked.

T

Top-down design
Top-down design begins with the whole problem and repeatedly breaks its steps into smaller named tasks or method calls.
Plan input, calculation, and reporting calls in main before filling in their helper bodies.

U

Unreachable statement
An unreachable statement is code Java determines cannot execute, such as a statement directly after return in the same block.
A print directly after an unconditional return in the same block is rejected by the compiler.

V

Void
The Java keyword void declares that a method returns no value, even if its body performs actions such as printing.
A void printTotal call cannot fill the right side of an int assignment just because it prints a number.

W

Widening conversion
A widening conversion changes a value to a permitted wider type, allowing an int argument to fit a double parameter.
Passing 12 to a double parameter gives it 12.0 without requiring an explicit cast.

About this lesson

By StudeliReport a mistake

Make your own Study Materials

Turn your notes, slides and documents into Study Guides, Practice Questions, Flashcards and 6 more tools.

Get Started