Skip to content
beginnerPhase 9 · Java Foundations

Methods

Define, call, overload methods. Understand parameters, return values, and pass-by-value.

1h
4 problems
Topic Progress0%

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

0/4solved
Predict Output: Pass-by-Value
Pass-by-Value

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
Predict Output: Method Overloading
Method Overloading

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 Bug: Return Type
Return Statements

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 Bug: Static Method
Static 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?

Question 1 options

2. How does Java pass parameters?

Question 2 options

3. Can a static method access instance variables?

Question 3 options

4. What is the return type of a method that prints to console?

Question 4 options

Flashcards

Question

What is method overloading?

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?

Answer

Always pass-by-value. Primitives copy the value. Objects copy the reference (but reference itself is copied).

Question

What is a static method?

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?

Answer

Variable arguments (int... nums) allows zero or more arguments of the same type. Must be the last parameter.

Question

What is Methods?

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) { ... }