Dev Learning Lab

The labs on this site need JavaScript to run. The same content is written out below.

Fundamentals › Java

Methods

What is a method, and how is declaring it different from calling it?

A method is a block of code that has a name. In the code, the part written with a name, parentheses, and braces, such as static int add(int a, int b) { ... }, is the declaration of the method. A declaration only states that "there is a block of code named add," so the code inside does not run just because it is declared. The code runs when you call the method by putting parentheses after its name, as in add(2, 3). The values 2 and 3 that you pass in the parentheses are stored in the variables a and b (the parameters) in the parentheses of the declaration, and return gives the calculated value back to the place that called the method. In this lab you delete the declaration and the calling line one at a time, and change how many times you call and how many values you pass. Each time, the same code is compiled and run, so you can see what the compiler reports and how many times add runs. (static is added so that main can call add without creating an object. This lab does not cover it.)

Checked against real execution · Twelve combinations were compiled with javax.tools on JDK 21, run, and checked against the results

Concepts in this lab

Method
A method is a named block of executable code that can receive a fixed number of values when it is called. A declaration consists of a return type, a name, a list of parameters in parentheses, and a body in braces, as in static int add(int a, int b) { ... }. A declaration only states that "there is a block of code like this," so the body does not run just because it is declared. It runs when the method is called. A method whose body is a block is an implemented method even if the block is empty. A method with a declared return type is a compile-time error if the body can run to its end without returning, so it must end with return or the like.
Method invocation
A method invocation, or calling a method, is an expression that runs the body of a method. You write the method name, then parentheses, and inside the parentheses the values to pass, as in add(2, 3). For each call the compiler looks for a method with that name and, for a method with a fixed number of arguments, checks that the number of values passed is the same as the number of parameters. If there is no method with that name, or the numbers do not match so that no method can be called at all, it is a compile-time error. At run time the values passed are evaluated in order from the left, they are stored in newly created parameter variables, and then the body runs. If you call the same method twice, the body also runs twice.
Parameters and arguments
A parameter is a variable written in the parentheses of a method declaration, and an argument is a value passed in the parentheses when the method is called. In add(int a, int b), a and b are parameters, and in add(2, 3), 2 and 3 are arguments. When the method is called, the values of the arguments are stored in order in parameter variables that are newly created for each call, and then the body runs. Inside the body, you use the name of a parameter like a variable. Declaring two parameters with the same name in one method is a compile-time error.
Return value (return)
A return value is the value that a method gives back to the place that called it, and the return statement is what gives it back. return ends the running of the method and sends control back to the place that called it. If you add an expression, as in return a + b, the expression is calculated first, and that value becomes the value of the call and takes the place of add(2, 3) in int sum = add(2, 3);. Using a return with a value in a method declared void, or in a constructor, is a compile-time error, and the type of the expression must fit the declared return type. When a return is used inside a try, the finally block runs first, and then control is passed back.

Try these

Running with the default settings

  1. You compile with javac. The compiler reads the source from the top and comes to the declaration of the add method. The declaration states that "there is a block of code named add that takes two int values and gives back one int value." The int a and int b in the parentheses are variables that hold the values passed in when add is called, and they are called parameters. The compiler only remembers this name. Compiling is not running, so the code inside add does not run.
  2. The compiler reads the call add(2, 3) in main. It found the name add in the declaration, and the two values passed (2, 3) match the two parameters (a, b) in number. It passes.
  3. Compiling succeeds, and the Main class file to run is created.
  4. You run it with java Main. Running starts at the first line of main. In the source, the declaration of add is written above main, but the code does not run in the order in which it is written. A declaration is not part of the running order, and up to this point the code in add has not run even once.
  5. In the line int sum = add(2, 3);, you meet the call add(2, 3). This form, with parentheses after the name, is what calls add, and the 2 and the 3 in the parentheses are the values passed. The values passed are stored in the parameters of add in order. 2 is stored in a and 3 is stored in b, and running moves from main into the code in add.
  6. The first line in add, System.out.println("add is running"), runs and prints add is running. The number of times add has run is 1.
  7. return a + b calculates a + b (2 + 3 is 5) and gives that value, 5, back to the place that called add. The running of add ends here, and running returns to main.
  8. The place where the call add(2, 3) was becomes the value that came back, 5, and 5 is stored in sum.
  9. System.out.println(sum) prints the 5 stored in sum.

Result of this run

Code

public class Main {
    // Declaration: a block of code named add. It does not run until it is called
    static int add(int a, int b) {
        System.out.println("add is running");
        return a + b;
    }

    public static void main(String[] args) {
        // Call: pass 2 and 3 to run add, and store the returned value in sum
        int sum = add(2, 3);
        System.out.println(sum);
    }
}

Assumptions of this model

The compiler and the runtime environment are JDK 21.0.12.1 (javac 21). All twelve combinations were compiled with javax.tools from the same source as the code on the screen (identical line by line). The ones that compiled successfully were loaded with a new class loader and Main.main was run, and the results were checked against the captured standard output. What was checked is whether compiling succeeded, the diagnostic code of the first error (compiler.err.cant.resolve.location.args and compiler.err.cant.apply.symbol, which are shown on the screen as the two error descriptions), the number of errors and the lines they occurred on, whether the Main class file was created, the output when run, and the number of times "add is running" appeared in that output. The fact that the step sentences rely on, that "running starts at the first line of main, and even if the declaration of add is above main it does not run first," was confirmed by running, in the same way, a separate source with one more output line added as the first line of main, and the output came in the order main started, add is running, 5. The documentation was checked by opening the Java Language Specification (Java SE 21) directly. That a method declaration declares executable code that can be invoked follows section 8.4; that the values passed in a call initialize newly created parameter variables before the body runs follows section 8.4.1; that a method body that is a block is an implementation follows section 8.4.7; that the argument expressions are evaluated in order from the left when a call is made follows section 15.12.4.2; that control passes to the method body after the argument values are stored in newly created parameter variables follows section 15.12.4.5; that a return with a value evaluates the expression, makes that value the value of the call, and passes control back to the caller follows section 14.17; and that only methods with the same number of arguments become candidates for the call (in the case of fixed-arity methods), and that it is a compile-time error if there is no candidate at all, follows section 15.12.2.1. Only part of section 15.12.2.1 could be read, and section 8.4.5 (the return type) could not be opened. The kinds of errors, the number of errors, and the lines they occur on are not set by the specification but were observed with this javac. This lab does not cover methods whose return type is void, creating several methods with the same name (overloading), methods that belong to an object, or variable arguments. How information is stacked up and removed each time a method is called is covered in "In-depth lab: Stack and heap".

Previous lab: Variables and types · Next lab: Classes and objects

Concepts in this lab

What this lab shows

Settings

Code


      
    

Diagram

Run comparison

Try these