Methods in Java
By the Syncfusion DevTutorials team · Last updated
Write and call Java methods with parameters and return values, overload them, use static and instance methods, varargs and recursion, and see how pass by value works.
Think about a coffee machine.
You press one button, and the machine does a whole sequence of work: heat water, grind beans, and pour the coffee. You do not need to repeat those steps yourself every time. You just press the button again when you want another cup.
A method works the same way. You write a set of steps once, give it a name, and call that name whenever you want the job done again.
In simple words: a method is a named block of code that does one job, and you can run it as many times as you like.
What You Will Learn
In this lesson, you will learn:
- Why methods make programs shorter and easier to maintain.
- How to declare a method and how to call it.
- How to send values into a method with parameters.
- How to get a value back with
return, and when to usevoid. - How to give several methods the same name with overloading.
- The difference between static methods and instance methods.
- How to accept any number of values with varargs.
- How a method can call itself with recursion.
- What pass by value means, and why it often surprises beginners.
Start With a Working Example
Press Run.
One method, called three times
public class Main {
public static void main(String[] args) {
greet("Asha");
greet("Ravi");
greet("Meena");
}
static void greet(String name) {
System.out.println("Hello, " + name + "! Welcome to the course.");
}
}
Expected output:
Hello, Asha! Welcome to the course.
Hello, Ravi! Welcome to the course.
Hello, Meena! Welcome to the course.
The greeting is written once, inside the greet method. main calls it three times with different names.
Try This
Change Hello to Hi inside greet. All three lines change, but you only edit one line.
Introduction to Methods
A method is a block of code with a name. It runs only when it is called.
You have already used methods in your first programs:
mainis a method. Java calls it to start your program.printlnis a method. You call it to print text.length()andtoUpperCase()are methods on aString.
Now you will write your own.
Why Methods Help
- No repeated code. Write a job once, then call it wherever you need it.
- Easier to fix. If the job has a bug, you fix it in one place.
- Easier to read. A name like
calculateTax()tells you what the code does. - Smaller pieces. A big problem becomes a set of smaller, simpler methods.
This idea is often called DRY: Don't Repeat Yourself.
Method Declaration
Declaring a method means writing it. A declaration has a header and a body.
static int add(int a, int b) {
return a + b;
}
| Part | Example | Meaning |
|---|---|---|
| Modifier | static | How the method can be called |
| Return type | int | The type of value the method gives back, or void for none |
| Name | add | What you call the method |
| Parameters | (int a, int b) | The values the method needs |
| Body | { return a + b; } | The code that runs |
Methods are written inside a class, but outside any other method. You cannot put one method inside another.
Method names use camelCase and usually start with a verb: calculateTotal, printReport, isValid.
Method Calling
Calling a method means running it. You write its name, followed by brackets.
When Java reaches a call, it:
- jumps into the method;
- runs the method's body from top to bottom;
- jumps back to the line that made the call and continues.
Java jumps into the method and comes back
public class Main {
public static void main(String[] args) {
System.out.println("1. main starts");
printLine();
System.out.println("3. back in main");
printLine();
System.out.println("4. main ends");
}
static void printLine() {
System.out.println("2. inside printLine");
}
}
Expected output:
1. main starts
2. inside printLine
3. back in main
2. inside printLine
4. main ends
printLine is written below main, but that does not matter. A method runs only when it is called, not when it is written.
Think of a phone call. You stop what you are doing, talk, hang up, and then continue from where you left off.
Method Parameters
A parameter is a variable in the method header. It receives a value when the method is called.
The value you send in the call is called an argument.
static void printBill(String item, int price) { ... } // item and price are parameters
printBill("Pen", 20); // "Pen" and 20 are arguments
Arguments fill the parameters in order
public class Main {
public static void main(String[] args) {
printBill("Notebook", 3, 45);
printBill("Pen", 10, 12);
}
static void printBill(String item, int quantity, int price) {
int total = quantity * price;
System.out.println(item + " x" + quantity + " = " + total);
}
}
Expected output:
Notebook x3 = 135
Pen x10 = 120
The arguments are matched to the parameters by position. The first argument goes into the first parameter, and so on.
The number, types, and order must all match. printBill(3, "Notebook", 45) does not compile because 3 is not a String.
Parameters are local variables. They only exist inside their method.
Return Values
A method can send a value back to the code that called it. This is called returning a value.
You do two things:
- write the type of the value before the method name, such as
intordouble; - use the
returnkeyword in the body to send the value back.
return sends a value back to the caller
public class Main {
public static void main(String[] args) {
double area = circleArea(7);
System.out.println("Area: " + area);
int bigger = max(18, 42);
System.out.println("Bigger: " + bigger);
System.out.println("Is 17 even? " + isEven(17));
}
static double circleArea(double radius) {
return 3.14 * radius * radius;
}
static int max(int a, int b) {
if (a > b) {
return a;
}
return b;
}
static boolean isEven(int number) {
return number % 2 == 0;
}
}
Expected output:
Area: 153.86
Bigger: 42
Is 17 even? false
circleArea(7) is replaced by the value it returns, 153.86. That value is stored in area.
You can use a method call anywhere you could use a value: in a variable, in a println, or inside a condition.
return also ends the method immediately. In max, if a > b is true, the line return b; never runs.
A method with a return type must return a value on every path. If one path can reach the end without a return, the compiler reports missing return statement.
Void Methods
A void method does a job but returns nothing. Its return type is void.
Use void when the method's job is an action, like printing, saving, or updating something.
A void method acts but gives nothing back
public class Main {
public static void main(String[] args) {
printStars(5);
printStars(3);
}
static void printStars(int count) {
if (count <= 0) {
return;
}
for (int i = 0; i < count; i++) {
System.out.print("*");
}
System.out.println();
}
}
Expected output:
*****
***
A void method can still use return; with no value. It just leaves the method early.
You cannot store the result of a void method. int x = printStars(5); does not compile, because there is nothing to store.
void method | Method with a return type | |
|---|---|---|
| Gives back a value? | No | Yes |
return | Optional, written as return; | Required, written as return value; |
| Typical job | Print, save, change something | Calculate, check, find something |
| Example | printStars(5); | int m = max(4, 9); |
Method Overloading
Method overloading means having several methods with the same name but different parameters.
Java picks the right one by looking at the arguments you pass.
Think of the word "play". You play a song, play a game, or play football. The word is the same, and the words after it tell you which meaning you want.
Same name, different parameters
public class Main {
public static void main(String[] args) {
System.out.println(add(2, 3));
System.out.println(add(2, 3, 4));
System.out.println(add(2.5, 3.5));
}
static int add(int a, int b) {
return a + b;
}
static int add(int a, int b, int c) {
return a + b + c;
}
static double add(double a, double b) {
return a + b;
}
}
Expected output:
5
9
6.0
add(2, 3)has twointvalues, so Java calls the first version.add(2, 3, 4)has three values, so Java calls the second.add(2.5, 3.5)has twodoublevalues, so Java calls the third.
Overloaded methods must differ in the number, types, or order of their parameters.
A different return type alone is not enough. Two methods named total() that differ only by return type cannot live in the same class, because a call like total() would not tell Java which one you mean.
Static Methods
A static method belongs to the class itself. You can call it without creating an object.
Every method so far has been static. main is static too, so Java can call it before any objects exist.
You call a static method by its name inside the same class, or with the class name from outside: ClassName.method().
Static methods are called on the class
public class Main {
public static void main(String[] args) {
System.out.println(Converter.celsiusToFahrenheit(100));
System.out.println(Converter.kmToMiles(10));
System.out.println(Math.max(8, 15));
}
}
class Converter {
static double celsiusToFahrenheit(double c) {
return c * 9 / 5 + 32;
}
static double kmToMiles(double km) {
return km * 0.625;
}
}
Expected output:
212.0
6.25
15
Converter.celsiusToFahrenheit(100) works without any Converter object.
Math.max is a static method from Java's own Math class. That is why you write Math.max, not new Math().max.
Static methods suit jobs that only need their parameters, like conversions and calculations.
Instance Methods
An instance method belongs to an object. It has no static keyword.
You first create an object with new. Then you call the method on that object with a dot.
An instance method can use the object's own data. Each object keeps its own values.
Each object runs the method with its own data
public class Main {
public static void main(String[] args) {
BankAccount asha = new BankAccount();
BankAccount ravi = new BankAccount();
asha.deposit(500);
asha.deposit(200);
ravi.deposit(1000);
asha.showBalance("Asha");
ravi.showBalance("Ravi");
}
}
class BankAccount {
int balance = 0;
void deposit(int amount) {
balance += amount;
}
void showBalance(String owner) {
System.out.println(owner + " has " + balance);
}
}
Expected output:
Asha has 700
Ravi has 1000
deposit and showBalance are instance methods. asha.deposit(500) changes only Asha's balance. Ravi's account is a separate object with its own balance.
| Static method | Instance method | |
|---|---|---|
| Keyword | static | none |
| Belongs to | The class | One object |
| How to call | ClassName.method() | object.method() |
| Needs an object? | No | Yes, created with new |
| Can use the object's own data? | No | Yes |
| Example | Math.max(3, 7) | name.length() |
A static method cannot call an instance method directly. Inside main, calling a non-static method gives non-static method ... cannot be referenced from a static context. Make the method static, or call it on an object.
Variable Arguments (varargs)
Sometimes you do not know how many values the caller will pass. Varargs (variable arguments) let a method accept any number of values of one type.
You write three dots after the type: int... numbers.
Inside the method, numbers is an array.
One method accepts any number of values
public class Main {
public static void main(String[] args) {
System.out.println(sum());
System.out.println(sum(5));
System.out.println(sum(10, 20, 30));
System.out.println(sum(1, 2, 3, 4, 5, 6));
}
static int sum(int... numbers) {
int total = 0;
for (int n : numbers) {
total += n;
}
return total;
}
}
Expected output:
0
5
60
21
The same sum method works with no values, one value, or six values.
Two rules for varargs:
- A method can have only one varargs parameter.
- It must be the last parameter.
static void report(String title, int... scores)is fine.static void report(int... scores, String title)is not.
System.out.printf and String.format use varargs. That is why they accept any number of values.
Recursive Methods
A recursive method is a method that calls itself.
Each call works on a smaller part of the problem until the answer becomes obvious.
Think of Russian nesting dolls. You open one doll and find a smaller one inside. You keep opening dolls until you reach the smallest one, which does not open.
Every recursive method needs two parts:
- a base case, which answers directly and stops the recursion;
- a recursive case, which calls the method again with a smaller problem.
Factorial
The factorial of 5, written 5!, is 5 × 4 × 3 × 2 × 1, which is 120.
Notice that 5! is 5 × 4!, and 4! is 4 × 3!. So factorial can be defined using a smaller factorial.
Factorial calls itself with a smaller number
public class Main {
public static void main(String[] args) {
System.out.println("5! = " + factorial(5));
System.out.println("1! = " + factorial(1));
}
static int factorial(int n) {
if (n <= 1) {
return 1; // base case
}
return n * factorial(n - 1); // recursive case
}
}
Expected output:
5! = 120
1! = 1
Here is what happens for factorial(4):
factorial(4) = 4 * factorial(3)
factorial(3) = 3 * factorial(2)
factorial(2) = 2 * factorial(1)
factorial(1) = 1 ← base case
factorial(2) = 2 * 1 = 2
factorial(3) = 3 * 2 = 6
factorial(4) = 4 * 6 = 24
The calls go down until they reach the base case. Then the answers come back up, one multiplication at a time.
Watching the Calls
This version prints a line on the way down and on the way back up:
Recursion goes down to the base case, then back up
public class Main {
public static void main(String[] args) {
countDown(3);
}
static void countDown(int n) {
if (n == 0) {
System.out.println("Lift off!");
return;
}
System.out.println("Going down: " + n);
countDown(n - 1);
System.out.println("Coming back: " + n);
}
}
Expected output:
Going down: 3
Going down: 2
Going down: 1
Lift off!
Coming back: 1
Coming back: 2
Coming back: 3
Each call waits for the call inside it to finish. So the "Coming back" lines print in reverse order.
A recursive method with no base case, or one that never reaches it, keeps calling itself. Each call uses a little memory, and the program soon stops with a StackOverflowError.
Pass by Value
When you call a method, Java gives it a copy of each argument. This is called pass by value.
The method works on its copy. Changing the copy does not change the original variable in the caller.
Think of photocopying a page and handing over the copy. If someone writes on the copy, your original page stays clean.
The method changes its copy, not the original
public class Main {
public static void main(String[] args) {
int score = 50;
addBonus(score);
System.out.println("score in main: " + score);
}
static void addBonus(int score) {
score += 10;
System.out.println("score in addBonus: " + score);
}
}
Expected output:
score in addBonus: 60
score in main: 50
addBonus got a copy of 50 and changed its copy to 60. The score in main was never touched.
To get the new value out, return it: score = addBonus(score);, with addBonus returning an int.
Passing an Array or an Object
For arrays and objects, the variable holds a reference, which is like an address. Java still passes a copy, but it is a copy of the address.
Both copies point to the same array. So a change made through the reference is seen by the caller.
A copied reference still points to the same array
public class Main {
public static void main(String[] args) {
int[] marks = {70, 80, 90};
addGrace(marks);
System.out.println("After addGrace: " + marks[0] + ", " + marks[1] + ", " + marks[2]);
replace(marks);
System.out.println("After replace: " + marks[0] + ", " + marks[1] + ", " + marks[2]);
}
static void addGrace(int[] list) {
for (int i = 0; i < list.length; i++) {
list[i] += 5;
}
}
static void replace(int[] list) {
list = new int[] {0, 0, 0};
}
}
Expected output:
After addGrace: 75, 85, 95
After replace: 75, 85, 95
addGrace changes the values inside the shared array, so main sees the change.
replace points its own copy of the reference at a brand-new array. That changes only the copy. main still points to the old array, so nothing changes there.
In simple words: Java always passes a copy. For a primitive, it copies the value. For an array or object, it copies the address, so both sides can reach the same object.
Common mistakes
The following mistakes are common when writing and calling methods. Each row shows what you see, why it happens and how to fix it.
| Symptom | Cause | Fix |
|---|---|---|
incompatible types at a method call | Arguments are in the wrong order or type | Match the parameter list exactly |
missing return statement | One path has no return | Return a value on every path |
| The method's result never appears | The returned value was not stored or used | Store it in a variable, or print it |
non-static method cannot be referenced from a static context | main called an instance method directly | Make the method static, or call it on an object |
| A variable is unchanged after a method call | Java passed a copy of the value | Return the new value and store it |
StackOverflowError | Recursion never reaches its base case | Add a base case and make each call smaller |
What to Remember
- A method is a named block of code. Declare it once, then call it as often as you need.
- Parameters receive values. The values you pass in a call are arguments, matched by position.
- A method with a return type must
returna value. Avoidmethod returns nothing. - Overloaded methods share a name but have different parameters.
- Static methods belong to the class. Instance methods belong to an object created with
new. - Varargs (
int... values) accept any number of values as an array. It must be the last parameter. - A recursive method calls itself and needs a base case to stop.
- Java always passes a copy. For an array or object, the copy still points to the same object.
Next: Arrays