Method Declaration
Method Syntax
public class Methods {
// Method declaration
// returnType methodName(parameters) {
// body
// return value;
// }
// void method (no return value)
public void greet(String name) {
System.out.println("Hello, " + name + "!");
}
// Method with return value
public int add(int a, int b) {
return a + b;
}
// Method returning boolean
public boolean isEven(int num) {
return num % 2 == 0;
}
public static void main(String[] args) {
Methods m = new Methods();
m.greet("Amazon"); // Hello, Amazon!
int sum = m.add(5, 3); // 8
boolean even = m.isEven(4); // true
}
}
Access Modifiers
public class AccessDemo {
// public: accessible everywhere
public void publicMethod() { }
// protected: accessible in same package and subclasses
protected void protectedMethod() { }
// default (no modifier): accessible in same package
void defaultMethod() { }
// private: accessible only within this class
private void privateMethod() { }
}
Method Signatures
// Method signature = name + parameter types
// Return type is NOT part of signature
public class Signature {
public int add(int a, int b) { return a + b; }
public double add(double a, double b) { return a + b; } // overload
public int add(int a, int b, int c) { return a + b + c; } // overload
}
Parameters and Arguments
Parameter Types
public class Parameters {
// Primitive parameters (pass by value)
public void modifyPrimitive(int x) {
x = 100; // only modifies local copy
}
// Reference parameters (pass reference by value)
public void modifyArray(int[] arr) {
arr[0] = 100; // modifies original array
}
// String parameters (immutable)
public void modifyString(String s) {
s = s + " world"; // creates new String, original unchanged
}
public static void main(String[] args) {
Parameters p = new Parameters();
int num = 5;
p.modifyPrimitive(num);
System.out.println(num); // 5 (unchanged)
int[] arr = {1, 2, 3};
p.modifyArray(arr);
System.out.println(arr[0]); // 100 (changed)
String str = "hello";
p.modifyString(str);
System.out.println(str); // hello (unchanged)
}
}
Variable Arguments (Varargs)
public class Varargs {
// Varargs: zero or more arguments of same type
public int sum(int... numbers) {
int total = 0;
for (int num : numbers) {
total += num;
}
return total;
}
// Mixed parameters (varargs must be last)
public void print(String label, int... values) {
System.out.print(label + ": ");
for (int v : values) {
System.out.print(v + " ");
}
System.out.println();
}
public static void main(String[] args) {
Varargs v = new Varargs();
System.out.println(v.sum()); // 0
System.out.println(v.sum(1)); // 1
System.out.println(v.sum(1, 2, 3)); // 6
System.out.println(v.sum(1, 2, 3, 4, 5)); // 15
v.print("Scores", 95, 87, 92); // Scores: 95 87 92
}
}
Parameter Naming
// Use descriptive names
public double calculateArea(double length, double width) {
return length * width;
}
// Avoid single letters (except loops)
public int findMax(int[] numbers) { // good
int max = numbers[0];
for (int i = 1; i < numbers.length; i++) {
if (numbers[i] > max) {
max = numbers[i];
}
}
return max;
}
Return Types
Return Types
public class ReturnTypes {
// void: no return value
public void printMessage(String msg) {
System.out.println(msg);
// no return statement needed
// return; // optional, can be used to exit early
}
// Primitive return types
public int getInt() { return 42; }
public double getDouble() { return 3.14; }
public boolean getBoolean() { return true; }
public char getChar() { return 'A'; }
// Reference return types
public String getString() { return "Hello"; }
public int[] getArray() { return new int[]{1, 2, 3}; }
// Return multiple values using array or object
public int[] minMax(int[] arr) {
int min = arr[0], max = arr[0];
for (int num : arr) {
if (num < min) min = num;
if (num > max) max = num;
}
return new int[]{min, max};
}
// Early return
public int divide(int a, int b) {
if (b == 0) return 0; // handle edge case
return a / b;
}
}
Return Best Practices
// Single return point (cleaner)
public boolean isEven(int num) {
return num % 2 == 0;
}
// Multiple returns for early exit
public String processUser(User user) {
if (user == null) return "Invalid user";
if (!user.isActive()) return "User inactive";
// Main logic
return "Hello, " + user.getName();
}
// Return null for optional values
public String findString(List<String> list, String target) {
for (String s : list) {
if (s.equals(target)) return s;
}
return null; // not found
}
Method Overloading
What is Method Overloading?
Multiple methods with the same name but different parameter lists.
public class Calculator {
// Overloaded add methods
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
public int add(int a, int b, int c) {
return a + b + c;
}
public String add(String a, String b) {
return a + b;
}
public static void main(String[] args) {
Calculator calc = new Calculator();
System.out.println(calc.add(5, 3)); // 8 (int version)
System.out.println(calc.add(2.5, 3.5)); // 6.0 (double version)
System.out.println(calc.add(1, 2, 3)); // 6 (three param version)
System.out.println(calc.add("Hello", " World")); // Hello World (String version)
}
}
Overloading Rules
public class OverloadingRules {
// VALID overloading: different parameter types
public void method(int a) { }
public void method(double a) { } // OK
// VALID overloading: different number of parameters
public void method(int a, int b) { }
public void method(int a) { } // OK
// VALID overloading: different order
public void method(int a, String b) { }
public void method(String a, int b) { } // OK
// INVALID: return type doesn't differentiate
// public int method(int a) { return 0; }
// public double method(int a) { return 0; } // COMPILE ERROR!
// INVALID: parameter name doesn't differentiate
// public void method(int x) { }
// public void method(int y) { } // COMPILE ERROR!
}
Overloading Examples
// Print methods
public class Printer {
public void print(String s) { System.out.println(s); }
public void print(int i) { System.out.println(i); }
public void print(double d) { System.out.println(d); }
public void print(boolean b) { System.out.println(b); }
public void print(String... strings) {
for (String s : strings) System.out.print(s + " ");
System.out.println();
}
}
// Math utility
public class MathUtils {
public static int max(int a, int b) { return (a > b) ? a : b; }
public static int max(int a, int b, int c) { return max(max(a, b), c); }
public static double max(double a, double b) { return (a > b) ? a : b; }
}
Pass-by-Value
Java is Pass-by-Value
Java always passes copies of values, never references themselves.
public class PassByValue {
// Primitive: copy of value
public void modifyPrimitive(int x) {
x = 100; // modifies local copy only
}
// Reference: copy of reference (points to same object)
public void modifyArray(int[] arr) {
arr[0] = 100; // modifies object through reference
}
// Reference: reassigning reference doesn't affect original
public void reassignReference(int[] arr) {
arr = new int[]{100, 200, 300}; // new local reference
}
public static void main(String[] args) {
PassByValue pbv = new PassByValue();
// Primitive: unchanged
int num = 5;
pbv.modifyPrimitive(num);
System.out.println(num); // 5
// Array: changed
int[] arr = {1, 2, 3};
pbv.modifyArray(arr);
System.out.println(arr[0]); // 100
// Reassign: unchanged
int[] arr2 = {1, 2, 3};
pbv.reassignReference(arr2);
System.out.println(arr2[0]); // 1
}
}
Why Java is Pass-by-Value
// This is what happens behind the scenes:
// When you call:
pbv.modifyPrimitive(num);
// Java copies the value of num into the parameter x
// x = 5 (copy)
// x = 100 (local change)
// num is still 5
// When you call:
pbv.modifyArray(arr);
// Java copies the reference (address) into the parameter arr
// arr points to same array object
// arr[0] = 100 modifies the object
// Original arr still points to same modified object
// When you call:
pbv.reassignReference(arr2);
// Java copies the reference
// arr = new int[]{100, 200, 300} creates new local reference
// arr2 still points to original array
Strings are Immutable
public class StringImmutable {
public void modifyString(String s) {
s = s + " world"; // creates new String object
}
public static void main(String[] args) {
StringImmutable si = new StringImmutable();
String str = "hello";
si.modifyString(str);
System.out.println(str); // hello (unchanged)
}
}
Passing Objects
// Objects are passed by reference value
class User {
String name;
User(String name) {
this.name = name;
}
}
public class ObjectPassing {
public void modifyUser(User user) {
user.name = "Modified"; // changes object
}
public void reassignUser(User user) {
user = new User("New"); // doesn't affect original
}
public static void main(String[] args) {
User user = new User("Original");
ObjectPassing op = new ObjectPassing();
op.modifyUser(user);
System.out.println(user.name); // Modified
op.reassignUser(user);
System.out.println(user.name); // Modified (unchanged)
}
}
Static Methods
What are Static Methods?
Belong to the class, not instances. Called without creating an object.
public class StaticDemo {
// Instance method
public void instanceMethod() {
System.out.println("Instance method");
}
// Static method
public static void staticMethod() {
System.out.println("Static method");
}
public static void main(String[] args) {
// Static method: call on class
StaticDemo.staticMethod();
// Instance method: need object
StaticDemo obj = new StaticDemo();
obj.instanceMethod();
}
}
Static vs Instance
public class Counter {
private static int totalCount = 0; // shared
private int count = 0; // per instance
public Counter() {
totalCount++; // increments shared counter
}
public void increment() {
count++; // increments instance counter
}
public static int getTotalCount() {
return totalCount; // can access static members
// return count; // ERROR: cannot access instance member
}
public int getCount() {
return count; // can access both
}
public static void main(String[] args) {
Counter c1 = new Counter();
Counter c2 = new Counter();
c1.increment();
System.out.println(c1.getCount()); // 1
System.out.println(c2.getCount()); // 0
System.out.println(Counter.getTotalCount()); // 2
}
}
Static Utility Methods
// Common patterns for static methods
public class StringUtils {
// Private constructor (utility class)
private StringUtils() { }
public static boolean isEmpty(String s) {
return s == null || s.isEmpty();
}
public static String reverse(String s) {
return new StringBuilder(s).reverse().toString();
}
public static int countOccurrences(String text, char target) {
int count = 0;
for (char c : text.toCharArray()) {
if (c == target) count++;
}
return count;
}
}
// Usage
String s = "Hello";
System.out.println(StringUtils.isEmpty(s)); // false
System.out.println(StringUtils.reverse(s)); // olleH
System.out.println(StringUtils.countOccurrences(s, 'l')); // 2
When to Use Static
// Use static for:
// 1. Utility methods (Math.abs, Arrays.sort)
// 2. Factory methods
// 3. Constants (static final)
// 4. State shared across instances
public class MathUtils {
public static final double PI = 3.141592653589793;
public static int abs(int n) {
return (n < 0) ? -n : n;
}
public static int max(int a, int b) {
return (a > b) ? a : b;
}
}
// Usage without object
int x = MathUtils.abs(-5); // 5
int y = MathUtils.max(10, 20); // 20
Practice Problems
What is the output of this code?
Example:
Input: public class Test { static void modify(int x, int[] arr) { x = 100; arr[0] = 100; } public static void main(String[] args) { int x = 5; int[] arr = {1, 2, 3}; modify(x, arr); System.out.println(x + " " + arr[0]); } }
Output: 5 100
Primitive x is unchanged (pass-by-value). Array arr is modified (reference passed by value).
Optimal Solution — O(1) time, O(1) space
Understand pass-by-value for primitives vs references
public class Test {
static void modify(int x, int[] arr) {
x = 100; // modifies local copy
arr[0] = 100; // modifies object through reference
}
public static void main(String[] args) {
int x = 5;
int[] arr = {1, 2, 3};
modify(x, arr);
System.out.println(x + " " + arr[0]); // 5 100
}
}Edge Cases:
- String immutability
- Object reassignment
What is the output of this code?
Example:
Input: public class Test { static void print(int x) { System.out.print("int "); } static void print(double x) { System.out.print("double "); } static void print(String x) { System.out.print("String "); } public static void main(String[] args) { print(5); print(5.0); print("5"); } }
Output: int double String
Each print call matches the corresponding overloaded method based on parameter type.
Optimal Solution — O(1) time, O(1) space
Match method signatures to arguments
public class Test {
static void print(int x) { System.out.print("int "); }
static void print(double x) { System.out.print("double "); }
static void print(String x) { System.out.print("String "); }
public static void main(String[] args) {
print(5); // matches int
print(5.0); // matches double
print("5"); // matches String
}
}Edge Cases:
- Auto-boxing
- Varargs matching
Find and fix the bug in this code.
Example:
Input: public class Bug { static int getMax(int a, int b) { if (a > b) { return a; } // missing return for else case } public static void main(String[] args) { System.out.println(getMax(5, 10)); } }
Output: Compilation error: missing return statement
Method must return a value in all code paths.
Optimal Solution — O(1) time, O(1) space
Add return statement for all paths
public class Bug {
static int getMax(int a, int b) {
if (a > b) {
return a;
}
return b; // add return for else case
}
public static void main(String[] args) {
System.out.println(getMax(5, 10)); // 10
}
}Edge Cases:
- Multiple return paths
- Void methods
Find and fix the bug in this code.
Example:
Input: public class Bug { int instanceVar = 10; static void printValue() { System.out.println(instanceVar); } public static void main(String[] args) { printValue(); } }
Output: Compilation error: non-static variable cannot be referenced from static context
Static methods cannot access instance variables directly.
Optimal Solution — O(1) time, O(1) space
Make variable static or create instance
public class Bug {
static int instanceVar = 10; // make static
static void printValue() {
System.out.println(instanceVar);
}
public static void main(String[] args) {
printValue(); // 10
}
}Edge Cases:
- Instance methods accessing statics
- Object reference in static
Quiz
1. What is method overloading?
2. How does Java pass parameters?
3. Can a static method access instance variables?
4. What is the return type of a method that prints to console?
Flashcards
Question
What is method overloading?
Click to reveal answer
Answer
Multiple methods with the same name but different parameter lists (types, number, or order). Return type doesn't differentiate.
Question
How does Java pass parameters?
Click to reveal answer
Answer
Always pass-by-value. Primitives copy the value. Objects copy the reference (but reference itself is copied).
Question
What is a static method?
Click to reveal answer
Answer
A method that belongs to the class, not instances. Called without creating an object. Cannot access instance variables directly.
Question
What is varargs in Java?
Click to reveal answer
Answer
Variable arguments (int... nums) allows zero or more arguments of the same type. Must be the last parameter.
Question
What is Methods?
Click to reveal answer
Answer
Methods is a key concept in Java programming.
Revision Notes
Key Takeaways
- 1.Methods group reusable code with clear input/output
- 2.Overloading uses different parameters, not return types
- 3.Java is always pass-by-value (copies values/references)
- 4.Static methods belong to the class, not instances
- 5.Use varargs for variable number of parameters
Interview Tips
- •Explain pass-by-value vs pass-by-reference
- •Know overloading rules and restrictions
- •Understand static vs instance methods
- •Use methods to decompose complex algorithms
Cheat Sheet
Methods Cheat Sheet
Declaration:
public returnType methodName(params) {
// body
return value;
}
Overloading: Same name, different parameters
int add(int a, int b)
double add(double a, double b)
Pass-by-Value:
- Primitives: copies value
- Objects: copies reference (object unchanged if reassigned)
Static:
- Belongs to class, not instance
- Called without object
- Cannot access instance members directly
Varargs:
public int sum(int... nums) { ... }