In programming, repeated writting the same logic across different parts of a codebase leads to redundancy, reduced maintainability, and inefficiency. To address this, Java provides methods—reusable blocks of code that encapsulate specific functionality. This approach mirrors how reference books solve recurring questions without repeated explanations.
What Is a Method?
A method is a self-contained block of code that performs a specific task. It promotes:
- Modularity: Breaking complex programs into manageable units.
- Reusability: Writing once and invoking multiple times.
- Maintainability: Updating logic in one place affects all usages.
- Readability: Clear separation of concerns improves code clarity.
Method Syntax and Definition
Methods in Java must be defined inside a class and follow this structure:
// Method definition
modifier returnType methodName([parameterType parameterName, ...]) {
// method body
return value; // if returnType is not void
}
Example 1: Leap Year Checker
public class DateUtils {
public static boolean isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
}
Example 2: Integer Addition
public class MathOperations {
public static int sum(int a, int b) {
return a + b;
}
}
Key Rules
- Use
public staticfor simple utility methods during early learning. - Specify
voidif the method returns nothing. - Method names follow lowerCamelCase.
- Parameters are comma-separated with declared types; empty parentheses mean no parameters.
- Methods cannot be nested within other methods.
- Java does not support forward declarations—methods must be defined before use or within the same class.
Method Invocation Flow
When a method is called:
- Control transfers to the method.
- Arguments are passed to parameters.
- The method body executes.
- Upon completion, control returns to the caller, optionally with a result.
Example: Multiple Calls to a Method
public class Calculator {
public static void main(String[] args) {
System.out.println("Before first call");
int result1 = sum(10, 20);
System.out.println("Result: " + result1);
System.out.println("Before second call");
int result2 = sum(30, 50);
System.out.println("Result: " + result2);
}
public static int sum(int x, int y) {
System.out.println("Adding: " + x + " + " + y);
return x + y;
}
}
Formal vs. Actual Paarmeters
Formal parameters (in method definition) act as placeholders. Actual parameters (during invocation) provide concrete values.
public static int triangularNumber(int n) {
return n * (n + 1) / 2;
}
// Usage
triangularNumber(10); // 10 is actual argument; n becomes 10
triangularNumber(100); // n becomes 100
Java uses pass-by-value for primitive types: the value is copied, so modifications to parameters don’t affect original variables.
Demonstration: Swapping Primitives
public class ParameterDemo {
public static void main(String[] args) {
int a = 10, b = 20;
swap(a, b);
System.out.println("After swap: a=" + a + ", b=" + b); // Still 10, 20
}
public static void swap(int x, int y) {
int temp = x;
x = y;
y = temp;
System.out.println("Inside swap: x=" + x + ", y=" + y); // 20, 10
}
}
This occurs because x and y are local copies in the method’s stack frame. Note: Reference types (e.g., arrays) behave differently—they pass object references by value.
Void Methods
Methods that perform actions without returning data use void:
public class Display {
public static void printPair(int x, int y) {
System.out.println("Values: x=" + x + ", y=" + y);
}
public static void main(String[] args) {
printPair(5, 15);
}
}
Method Overloading
Often, similar operations apply to different data types (e.g., adding integers vs. doubles). Instead of creating distinct method names (addInt, addDouble), Java supports method overloading.
Overloading Rules
Methods are overloaded when they share the same name but differ in:
- Number of parameters
- Parameter types
- Order of parameter types
Return type alone does not constitute overloading.
Example: Overloaded sum Methods
public class MathUtils {
public static int sum(int a, int b) {
return a + b;
}
public static double sum(double a, double b) {
return a + b;
}
public static double sum(double a, double b, double c) {
return a + b + c;
}
public static void main(String[] args) {
System.out.println(sum(3, 4)); // Calls int version
System.out.println(sum(2.5, 3.5)); // Calls double (2-arg)
System.out.println(sum(1.0, 2.0, 3.0)); // Calls double (3-arg)
}
}
Method Signature
The compiler distinguishes overloaded methods using their signature, which includes:
- Method name
- Parameter types (in order)
Return type is not part of the signature. Thus, two methods differing only in return type cause a compilation error.
Internally, the JVM uses mangled names based on class, method name, and parameter descriptors to uniquely identify each method—a detail visible via tools like javap -v.