As your programs grow beyond simple sequential scripts, writing all logic inside public static void main(String[] args) becomes messy, repeated, and impossible to maintain.
Imagine building a banking system where you need to format currency, validate account numbers, and compute interest in twenty different places. Copy-pasting the same lines of code creates massive duplication, increases bugs, and makes updates tedious.
This is where Methods help.
A Method is a named, reusable block of code that performs a specific task. You define a method once and invoke (call) it whenever and wherever needed.
Methods enable:
- Reusability (DRY - Don't Repeat Yourself): Write logic once, run it anywhere.
- Abstraction: Use a method knowing what it does without cluttering your code with how it does it.
- Modularity: Break complex problems into smaller, manageable, and readable functions.
- Maintainability & Testing: Update or debug logic in one central place.
A method definition in Java consists of several key components:
public static int calculateSum(int a, int b) {
int result = a + b;
return result;
}- Access Modifier (
public,private,protected, package-private): Defines where the method can be called from. - Non-Access Modifier (
static,final,abstract): Optional keyword.staticmeans the method belongs to the class itself rather than instances of the class. - Return Type (
void,int,double,boolean,String, etc.): Specifies the type of data returned to the caller. Usevoidif no value is returned. - Method Name (
calculateSum): Descriptive, lowerCamelCase name representing the method's action. - Parameter List (
(int a, int b)): Comma-separated list of formal parameters (inputs) accepted by the method. - Method Body (
{ ... }): The block of code executed when the method is invoked. - Return Statement (
return result;): Yields the output value back to the caller and terminates method execution.
1. BasicMethod.java — Declaration & Invocation
Concept: Methods must be declared inside a class body (outside of other methods) and called from within main() or other methods.
package javakb.ch04_methods;
public class BasicMethod {
// Static method defined outside main()
public static void greet() {
System.out.println("Hello! You are inside the greet() method.");
}
public static void greetUser(String name) {
System.out.println("Welcome to Java Methods, " + name + "!");
}
public static void main(String[] args) {
// Invoking greet() method multiple times
greet();
greet();
// Invoking method with arguments
greetUser("Harsh");
}
}- Why
static? Themain()entry point isstatic. Static methods can directly call otherstaticmethods in the same class without instantiating an object (new ClassName()). - Method Execution Flow: Execution begins in
main(). Whengreet()is called, control jumps togreet(), runs its body, and returns control back tomain().
2. MethodParameters.java — Parameters & Pass-by-Value
Concept:
- Formal Parameters: Variables declared in the method definition signature (e.g.,
int a, int b). - Actual Arguments: Concrete values or variables passed to the method during invocation (e.g.,
add(10, 20)).
Java NEVER uses Pass-by-Reference. Whenever you pass an argument into a method, Java creates a copy of the value.
| Data Type | What gets copied into parameter? | Modifying parameter inside method affects caller? |
|---|---|---|
Primitive Types (int, double, boolean) |
A copy of the primitive value | No. Changes in method are lost upon exit. |
| Reference Types (Objects, Arrays) | A copy of the memory address (reference) | Elements/Fields: Yes (both references point to the same object in heap). Reference Reassignment: No. |
// Primitive Pass-by-Value
public static void modifyPrimitive(int number) {
number = 999; // Modifies local copy only
}
// Reference Pass-by-Value: Mutating array contents
public static void modifyArrayElements(int[] arr) {
arr[0] = 777; // Mutates element in the shared heap object
}
// Reference Pass-by-Value: Reference reassignment
public static void reassignReference(int[] arr) {
arr = new int[]{100, 200, 300}; // Reassigns local reference copy only
}3. ReturnValues.java — Return Types & Guard Clauses
Concept: Methods can compute and return data back to the caller. The return type in the method signature must match (or be compatible with) the returned value's data type.
// Returns an int
public static int add(int a, int b) {
return a + b;
}
// Returns a double with correct parenthesis precedence
public static double average(double a, double b, double c) {
return (a + b + c) / 3.0; // Correct: (a + b + c) / 3.0
}The return keyword instantly exits the method. In void methods, return; can be used without a value to break out of execution early when encountering invalid input or boundary conditions:
public static void printEligibility(int age) {
if (age < 0) {
System.out.println("Invalid age!");
return; // Guard clause: Exit early
}
System.out.println("Valid age: " + age);
}4. MethodOverloading.java — Compile-Time Polymorphism
Concept: Method Overloading occurs when multiple methods in the same class share the exact same name but have different parameter lists.
- Methods MUST have the same name.
- Methods MUST have different parameter lists (differ by number of parameters, parameter data types, or parameter order).
- Return type CANNOT be used to distinguish overloaded methods. Changing only the return type produces a compile error.
public class MethodOverloading {
// Overload 1: Two int params
public static int add(int a, int b) { return a + b; }
// Overload 2: Three int params (different parameter count)
public static int add(int a, int b, int c) { return a + b + c; }
// Overload 3: Two double params (different data type)
public static double add(double a, double b) { return a + b; }
// Overload 4 & 5: Different parameter order
public static void display(String text, int num) {}
public static void display(int num, String text) {}
}If an exact parameter type match is not found, Java automatically promotes smaller types to larger compatible types (e.g., byte → short → int → long → float → double).
5. VariableScope.java — Scopes & Variable Shadowing
Concept: Scope defines the boundary within which a declared variable is accessible and valid.
+-----------------------------------------------------------+
| Class Scope (Static variables - accessible class-wide) |
| +---------------------------------------------------+ |
| | Method Local Scope (Accessible within method) | |
| | +-------------------------------------------+ | |
| | | Block Scope ({ ... } inside loops/if) | | |
| | +-------------------------------------------+ | |
| +---------------------------------------------------+ |
+-----------------------------------------------------------+
- Class / Static Scope: Variables declared inside class with
static. Alive for the duration of the application. - Method / Local Scope: Variables declared inside a method. Created when method is invoked, destroyed when method returns.
- Block Scope: Variables declared inside
{ ... }(e.g.,if,for,while). Visible only inside that specific block.
When a local or block variable shares the exact same name as a class-level variable, the local variable shadows (masks) the class variable within that scope. Access the class variable using ClassName.variableName.
6. RecursionIntro.java — Fundamentals of Recursion
Concept: Recursion occurs when a method invokes itself to solve a smaller instance of the same problem.
Every valid recursive method requires two essential parts:
- Base Case: The stopping condition that halts recursive calls.
- Recursive Step: Calling the method with a modified (reduced) subproblem.
// Factorial calculation: n! = n * (n - 1)!
public static int factorial(int n) {
if (n <= 1) {
return 1; // 1. Base Case
}
return n * factorial(n - 1); // 2. Recursive Step
}For factorial(3):
Push factorial(3) -> 3 * factorial(2)
Push factorial(2) -> 2 * factorial(1)
Push factorial(1) -> returns 1 (Base Case Hit!)
Pop factorial(1): returns 1
Pop factorial(2): 2 * 1 = 2
Pop factorial(3): 3 * 2 = 6
Warning (
StackOverflowError): If a recursive method lacks a base case or fails to reach it, stack frames fill up the JVM execution stack, causing ajava.lang.StackOverflowError.
7. VarargsDemo.java — Variable-Length Arguments
Concept: Introduced in Java 5, Varargs (Variable Arguments) allows a method to accept zero, one, or multiple arguments of a specified data type without explicitly creating an array at the call site.
public static int sum(int... numbers) {
int total = 0;
for (int n : numbers) {
total += n;
}
return total;
}Java converts int... numbers into an array parameter (int[] numbers) behind the scenes.
- A method can have at most ONE varargs parameter.
- The varargs parameter MUST BE THE LAST parameter in the parameter list.
// VALID public static void log(String tag, double... values) {} // INVALID (Compile Error) // public static void log(double... values, String tag) {}
8. ConsoleCalculator.java — Chapter 4 Mini Project
Project Objective: Build a clean, method-driven, menu-based interactive console calculator application.
- Separate calculations into individual methods:
add(),subtract(),multiply(),divide(), andsumVarargs(). - Safe division handling with explicit division-by-zero check.
- Interactive user loop with
Scannerand modernswitchexpression/statement.
// Method signature examples from ConsoleCalculator:
public static double add(double a, double b) { return a + b; }
public static double subtract(double a, double b) { return a - b; }
public static double multiply(double a, double b) { return a * b; }
public static double divide(double a, double b) {
if (b == 0) {
System.out.println("Error: Division by zero!");
return Double.NaN;
}
return a / b;
}
public static double sumVarargs(double... numbers) { ... }- Single Responsibility Principle (SRP): Each method should do one thing well. If a method calculates tax, formats receipt, and saves to database, split it into 3 separate methods.
- Meaningful & Action-Oriented Names: Use verbs for method names (
calculateTotal,isEven,findUserById). - Keep Parameter Count Small: Ideally 0 to 3 parameters. If a method requires 6+ parameters, consider passing an object.
- Avoid Side Effects: A method should ideally compute and return a result without unexpectedly mutating global static state.
- Use Guard Clauses: Return early on invalid parameters to keep code flat and avoid deep nested
if-elseblocks.
Methods are central to Data Structures & Algorithms and Technical Interviews:
- Stack Frames & Memory Allocation: Each method invocation creates a Stack Frame on the Call Stack containing local variables and parameter values. Stack frames are popped upon method return.
- Pass-by-Value Trap: Common interview trick questions test whether primitive changes or reference reassignments in methods affect original variables in
main(). - Recursion in DSA: Recursion is fundamental for Tree Traversals (Inorder, Preorder, Postorder), Graph Traversal (DFS), Backtracking (N-Queens, Sudoku Solver), and Divide & Conquer (MergeSort, QuickSort).
- Write a method
isPalindrome(String str)that returnstrueif a string is a palindrome. - Create an overloaded method
calculateAreathat calculates the area of a circle (radius), rectangle (width, height), and triangle (base, height, boolean isTriangle). - Write a recursive method
power(int base, int exponent)to compute base raised to exponent. - Create a varargs method
findMax(int... numbers)that returns the maximum value among all arguments passed. - Write a method
reverseArray(int[] arr)and verify whether changes persist inmain().
- Method: A named reusable block of code (
returnType name(params)). - Static Methods: Called without creating class instances.
- Pass-by-Value: Java passes copies of primitive values and copies of object references.
- Return Statement: Exits method and returns value (or exits early in
void). - Overloading: Same name, different parameter lists (resolved at compile-time).
- Scope: Local variables live only inside their method/block.
- Recursion: Method calls itself with a Base Case and Recursive Step.
- Varargs (
type... name): Accepts variable number of arguments as an array.