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
- Default settings — The declaration is present and add(2, 3) is called once. add runs once and 5 comes back.
- Delete the calling line — Even if the declaration stays, the code in add does not run unless it is called.
- Call add(2, 3) twice — Each call runs the code in add again.
- Delete the declaration of add and only call it — There is nothing to call, so you get a compile error.
- Pass only one value — The number of values passed does not match the number of parameters, so you get a compile error.
Running with the default settings
- 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.
- 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.
- Compiling succeeds, and the Main class file to run is created.
- 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.
- 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.
- 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.
- 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.
- The place where the call add(2, 3) was becomes the value that came back, 5, and 5 is stored in sum.
- System.out.println(sum) prints the 5 stored in sum.
Result of this run
- A method is a block of code that has a name. The declaration of add only states that "there is a block of code named add," and the real running happened when add was called by putting parentheses after its name, as in add(2, 3). The 2 and the 3 passed in the call were stored in the parameters a and b, and return gave the sum, 5, back to the caller and it was stored in sum.
- The declaration was above main, but it did not run first. Running starts at the first line of main, and the code in add ran once, at the moment add(2, 3) was reached.
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