☕ Java Backend Course

Methods in Java
Complete Deep Dive

Theory se lekar Memory Model, Overloading, Recursion, Varargs aur Practice Programs tak — ek hi jagah, sab kuch, depth mein.

10
Chapters
50+
Code Examples
30+
Practice Programs
4
Advanced Topics
Full
Theory Covered
01

Method Kya Hai?

Complete Theory · Memory Model · Why Methods · Stack Frame · Method vs Function

📖 Core Definition

Method — Ek Naam, Ek Kaam

Method ek named block of code hai jo ek specific task karta hai. Isko baar baar call karke code reuse hota hai — ek baar likho, hazaar baar use karo. Java mein har method kisi class ke andar hota hai (C/C++ ke free functions ki tarah nahi).

Soch lo bina methods ke: agar 10 jagah same calculation karni ho, to 10 baar same code likhna padega. Method se ek baar likhoo, 10 jagah call karo. Ye DRY principle (Don't Repeat Yourself) hai — professional backend dev ka pehla rule.

Java mein method calling pe Stack Frame create hota hai — local variables, parameters aur return address isme store hote hain. Method return hone par stack frame destroy ho jaata hai. Isliye local variables method ke baad accessible nahi hote.

Formal Definition: A method in Java is a named, reusable block of code inside a class that performs a specific task, optionally accepts parameters, and optionally returns a value. It encapsulates behavior, promotes code reuse, and improves readability.
Stack Memory — Method Call Stack
printSum() Frame
local: sum=55
↓ calls
add(a, b) Frame
params: a=10, b=20 | return: 30
↓ calls
main() Frame
local: args[] ref
Method call hone par naya frame push hota hai · Return hone par pop hota hai · Stack top = currently executing method
🧠 Method vs Function — Java mein Difference

Java Mein Sirf Methods Hain, Functions Nahi

Function (C/Python style): Kisi class ke baahir exist kar sakta hai, independently call hota hai. def greet(): ya void greet() {} class ke baahir — possible in C/Python.

Method (Java style): Hamesha kisi class ka hissa hota hai. Java purely object-oriented hai — koi bhi code class ke baahir nahi ho sakta. public static void main(String[] args) bhi class Main ke andar hai.

Python/JavaScript developers ko confuse hota hai — Java mein "function" word technically wrong hai. Hamesha "method" bolna chahiye interviews mein.

♻️

Code Reuse

Ek baar likhke baar baar call karo — DRY principle. Maintenance bhi easy hoti hai.

📦

Encapsulation

Complex logic ek method mein chhupa do — caller ko andar ki details jaanno zaroori nahi.

🧪

Testability

Chhhote methods easily unit-tested hote hain. Ek kaam, ek method — Single Responsibility.

📖

Readability

calculateTax() padhne se pata chalta hai kya hoga — 50 lines padhne ki zaroorat nahi.

🔄

Modularity

Bade programs chhhote methods mein todna — modular design. Team mein kaam baantna easy.

🐛

Debugging

Bug dhundna easy — sirf method mein dekho. Poora program nahi.

🌐 Real-World Uses in Backend

Methods in Production Code

  • Spring Boot Controller: Har HTTP endpoint ek method hai — @GetMapping, @PostMapping annotations methods pe lagate hain
  • Service Layer: Business logic methods — createOrder(), processPayment(), sendEmail()
  • Utility Classes: StringUtils.isEmpty(), DateUtils.format() — static helper methods
  • DAO Layer: findById(), save(), deleteAll() — database operation methods
  • Validation: isValidEmail(), isStrongPassword() — reusable validation methods
  • Algorithm Implementation: Sorting, searching, hashing sab methods mein encapsulate hote hain
02

Method Syntax

Access Modifiers · Return Type · Method Name · Parameters · Body

📖 Complete Syntax Breakdown

Method ke 5 Parts — Ek Ek Samjho

Java method ka full syntax: [access_modifier] [static] return_type method_name(parameter_list) { body }

  • Access Modifier: public / private / protected / (default) — kaun call kar sakta hai
  • static keyword: Object banaye bina class se directly call kar sako. Math.sqrt() static hai.
  • Return Type: Method kya return karega — int, String, void (kuch nahi) etc.
  • Method Name: camelCase mein — calculateTax, getStudentName, printReport
  • Parameters: Method ke andar kya data pass karna hai — (int a, int b), (String name)
Method Anatomy — Parts Breakdown
ACCESS MODIFIER RETURN TYPE NAME(PARAMS) { BODY }
public static int add(int a, int b) { return a + b; }
↑ public = sab call kar sakte ↑ static = object nahi chahiye ↑ int = integer return hoga ↑ add = method ka naam ↑ a,b = inputs
Access ModifierSame ClassSame PackageSubclassAnywhereUse Case
publicAPIs, public interface
protectedInheritance ke liye
(default/package)Internal package use
privateHelper methods, hide logic
EX 2.1

Method Types — 4 Combinations (void, return, params, no-params)

Chaar basic patterns — bina return, with return, bina parameters, with parameters. Ye sab real projects mein daily use hote hain.
public class MethodTypes {

    // ── TYPE 1: void + no parameters ──
    // Kuch return nahi karta, kuch input nahi leta
    // Use: print greeting, log karo, display karo
    static void greet() {
        System.out.println("Namaste! Java Seekh Rahe Ho?");
    }

    // ── TYPE 2: void + parameters ──
    // Kuch return nahi, lekin input leta hai
    // Use: print with data, log with message
    static void greetPerson(String name, int age) {
        System.out.println("Hello, " + name + "! Tumhari age " + age + " hai.");
    }

    // ── TYPE 3: return type + no parameters ──
    // Kuch return karta hai, input nahi
    // Use: getCurrentTime(), getVersion(), getSystemInfo()
    static String getWelcomeMessage() {
        return "Java Methods Complete Guide mein Aapka Swagat!";
    }

    // ── TYPE 4: return type + parameters ──  ← MOST COMMON
    // Input leta hai, process karta hai, result deta hai
    // Use: calculate, transform, validate, convert
    static double calculateCircleArea(double radius) {
        return Math.PI * radius * radius;
    }

    static boolean isEven(int n) {
        return n % 2 == 0;
    }

    static int add(int a, int b) {
        return a + b;
    }

    public static void main(String[] args) {
        greet();                              // TYPE 1 call
        greetPerson("Rahul", 22);            // TYPE 2 call

        String msg = getWelcomeMessage();     // TYPE 3 call, store result
        System.out.println(msg);

        double area = calculateCircleArea(5.0); // TYPE 4 call
        System.out.printf("Circle area (r=5): %.4f%n", area);

        System.out.println("10 is even: " + isEven(10));
        System.out.println("7 is even:  " + isEven(7));
        System.out.println("3 + 7 = " + add(3, 7));
    }
}
▶ Output
Namaste! Java Seekh Rahe Ho? Hello, Rahul! Tumhari age 22 hai. Java Methods Complete Guide mein Aapka Swagat! Circle area (r=5): 78.5398 10 is even: true 7 is even: false 3 + 7 = 10
EX 2.2

Method Calling Patterns — Direct, Chain, Nested, Store

Ek method ko 4 alag tareekon se call kar sakte ho. Production code mein sab patterns milte hain.
public class CallingPatterns {

    static int    square(int n)            { return n * n; }
    static int    cube(int n)              { return n * n * n; }
    static int    add(int a, int b)       { return a + b; }
    static String format(String s)          { return "[" + s.toUpperCase() + "]"; }
    static void   printLine(String msg)     { System.out.println(msg); }

    public static void main(String[] args) {

        // PATTERN 1: Result variable mein store karo
        int sq = square(7);
        System.out.println("7^2 = " + sq);

        // PATTERN 2: Direct — result seedha use karo
        System.out.println("5^3 = " + cube(5));

        // PATTERN 3: Nested calls — ek method ka output doosre ka input
        System.out.println("square(cube(2)) = " + square(cube(2))); // cube(2)=8, square(8)=64
        System.out.println("add(square(3), cube(2)) = " + add(square(3), cube(2))); // 9+8=17

        // PATTERN 4: Method result seedha print mein
        printLine(format("hello world"));  // format karo phir print karo

        // PATTERN 5: Method inside condition
        if (square(4) > 10) {
            System.out.println("4^2 is greater than 10");
        }

        // PATTERN 6: Method result in calculation
        int result = square(3) + square(4);  // 9 + 16 = 25 (Pythagorean theorem!)
        System.out.println("3^2 + 4^2 = " + result);
    }
}
▶ Output
7^2 = 49 5^3 = 125 square(cube(2)) = 64 add(square(3), cube(2)) = 17 [HELLO WORLD] 4^2 is greater than 10 3^2 + 4^2 = 25
03

Return Types

void · Primitives · Objects · Arrays · Multiple Returns · Early Return

📖 Theory — Return Types Deep Dive

Method Return — Complete Samajhna

Method ka return type declare karta hai ki ye method kya dega caller ko. void matlab kuch nahi — sirf side effects (print, modify, etc.).

return statement do kaam karta hai: (1) value wapas bhejta hai caller ko, (2) method execution immediately rok deta hai. Isliye isse "early return" ya "guard clause" ke liye use karte hain.

void methods mein return; (bina value) likh sakte ho sirf loop ya early exit ke liye. Primitive types seedha value copy karta hai, object return type mein reference jaata hai.

💡
Compilation Rule: Agar return type void nahi hai, to compiler ensure karta hai ki method ke sare possible paths pe return statement ho. Ek bhi path return ke bina → compilation error. Ye Java ka safety feature hai.
EX 3.1

Return Types — Primitives, String, Array, Object

Har type ka return — int se lekar array tak. Array return karna kaafi common hai backend APIs mein.
import java.util.Arrays;

public class ReturnTypes {

    // Primitive int return
    static int factorial(int n) {
        int result = 1;
        for (int i = 2; i <= n; i++) result *= i;
        return result;
    }

    // boolean return — guard clause / early return pattern
    static boolean isPrime(int n) {
        if (n < 2) return false;          // early return — guard
        if (n == 2) return true;           // early return — special case
        if (n % 2 == 0) return false;      // early return — even numbers
        for (int i = 3; i * i <= n; i += 2)
            if (n % i == 0) return false;
        return true;
    }

    // String return
    static String grade(int marks) {
        if (marks >= 90) return "A+";
        if (marks >= 80) return "A";
        if (marks >= 70) return "B";
        if (marks >= 60) return "C";
        if (marks >= 45) return "D";
        return "F";              // sare cases cover — compiler happy
    }

    // double return — complex calculation
    static double bmi(double weightKg, double heightM) {
        if (heightM <= 0) return -1;      // invalid input guard
        return weightKg / (heightM * heightM);
    }

    // Array return — heap pe naya array create hota hai
    static int[] getEvenNumbers(int limit) {
        int count = limit / 2;
        int[] evens = new int[count];
        for (int i = 0; i < count; i++) evens[i] = (i + 1) * 2;
        return evens;  // reference return hota hai, copy nahi
    }

    // void method — early return pattern
    static void printPositives(int[] arr) {
        if (arr == null || arr.length == 0) {
            System.out.println("Empty or null array!");
            return;  // early exit — void mein return value nahi chahiye
        }
        System.out.print("Positives: ");
        for (int n : arr) if (n > 0) System.out.print(n + " ");
        System.out.println();
    }

    public static void main(String[] args) {
        System.out.println("5! = " + factorial(5));
        System.out.println("7! = " + factorial(7));
        System.out.println("17 prime? " + isPrime(17));
        System.out.println("15 prime? " + isPrime(15));

        System.out.println("85 marks → Grade: " + grade(85));
        System.out.println("42 marks → Grade: " + grade(42));

        System.out.printf("BMI(70kg,1.75m) = %.2f%n", bmi(70, 1.75));

        int[] evens = getEvenNumbers(10);
        System.out.println("Evens up to 10: " + Arrays.toString(evens));

        printPositives(new int[]{-3, 5, -1, 8, 0, 12, -7});
        printPositives(null);  // null safety test
    }
}
▶ Output
5! = 120 7! = 5040 17 prime? true 15 prime? false 85 marks → Grade: A 42 marks → Grade: F BMI(70kg,1.75m) = 22.86 Evens up to 10: [2, 4, 6, 8, 10] Positives: 5 8 12 Empty or null array!
04

Parameters & Arguments

Formal vs Actual · Multiple Params · Default Values Pattern · Array Params

📖 Parameter vs Argument — Confusion Door Karo

Parameter aur Argument — Different Cheezein Hain

Parameter (Formal Parameter): Method definition mein jo variable declare karte ho — ye placeholder hai. static int add(int a, int b) mein a aur b parameters hain.

Argument (Actual Parameter): Method call karte waqt jo actual value pass karte ho. add(10, 20) mein 10 aur 20 arguments hain.

Parameters definition mein hote hain, arguments call mein. Interview mein ye distinction poochha jaata hai — "function parameters" aur "function arguments" ek nahi hain.

EX 4.1

Parameter Patterns — Multiple, Array, Default-Value Simulation

Multiple parameters, array as parameter, Java mein default parameter simulate karna — sab real patterns.
import java.util.Arrays;

public class ParameterPatterns {

    // ── Multiple Parameters ──
    static double simpleInterest(double principal, double rate, int time) {
        return (principal * rate * time) / 100.0;
    }

    // ── Array as Parameter — reference pass hoti hai ──
    static double average(int[] nums) {
        if (nums == null || nums.length == 0) return 0;
        int sum = 0;
        for (int n : nums) sum += n;
        return (double) sum / nums.length;
    }

    // ── Default Value Simulation via Overloading ──
    // Java mein default params nahi hain (Python ki tarah)
    // Overloading se simulate karte hain
    static String formatName(String first, String last, String title) {
        return title + " " + first + " " + last;
    }
    static String formatName(String first, String last) {
        return formatName(first, last, "Mr/Ms");  // default title
    }
    static String formatName(String first) {
        return formatName(first, "");  // only first name
    }

    // ── 2D Array as Parameter ──
    static int matrixSum(int[][] mat) {
        int total = 0;
        for (int[] row : mat)
            for (int v : row) total += v;
        return total;
    }

    // ── String Parameter — immutable, so always copied semantically ──
    static String repeat(String s, int times) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < times; i++) sb.append(s);
        return sb.toString();
    }

    public static void main(String[] args) {
        System.out.printf("SI(1000, 5%%, 3yr) = %.2f%n", simpleInterest(1000, 5, 3));

        int[] marks = {85, 92, 78, 96, 88};
        System.out.printf("Average marks = %.2f%n", average(marks));

        System.out.println(formatName("Rahul", "Sharma", "Mr"));
        System.out.println(formatName("Priya", "Gupta"));
        System.out.println(formatName("Rohan"));

        int[][] mat = {{1,2,3},{4,5,6},{7,8,9}};
        System.out.println("Matrix sum = " + matrixSum(mat));

        System.out.println(repeat("Java! ", 3));
    }
}
▶ Output
SI(1000, 5%, 3yr) = 150.00 Average marks = 87.80 Mr Rahul Sharma Mr/Ms Priya Gupta Mr/Ms Rohan Matrix sum = 45 Java! Java! Java!
05

Call by Value vs Call by Reference

Java ka #1 Interview Question · Primitives vs Objects · Mutation Proof

🔥 Most Important Concept

Java is ALWAYS Call by Value — Lekin Samajhna Padega

Simple answer (wrong way to remember): "Primitives call by value, objects call by reference."

Correct answer: Java HAMESHA call by value hai. Lekin objects ke liye, jo value pass hoti hai wo reference ka copy hota hai (not the object itself).

Primitives: Actual value ka copy pass hota hai. Method ke andar change karne se original variable unchanged rehta hai.

Objects/Arrays: Reference (address) ka copy pass hota hai. Dono (caller aur callee) same heap object ko point karte hain — isliye object ke fields ya array elements change hote hain original mein bhi. Lekin agar method mein obj = new Something() karo, to sirf local reference change hoti hai, original nahi.

EX 5.1

Call by Value — Complete Proof with Diagrams in Code

Primitive swap fail hoga, array modify succeed karega, object reassign original ko affect nahi karega. Teeno cases prove karo.
import java.util.Arrays;

public class CallByValue {

    // ── CASE 1: Primitive — original UNCHANGED ──
    static void trySwap(int a, int b) {
        int temp = a; a = b; b = temp;  // sirf local copies swap huin
        System.out.println("  Inside trySwap: a=" + a + ", b=" + b);
    }

    // ── CASE 2: Array — original CHANGED (same heap object) ──
    static void doubleArray(int[] arr) {
        for (int i = 0; i < arr.length; i++) arr[i] *= 2;  // same object modify
    }

    // ── CASE 3: Object reassign — original UNCHANGED ──
    static void tryReassign(int[] arr) {
        arr = new int[]{100, 200, 300};  // local reference change, original nahi
        System.out.println("  Inside tryReassign: " + Arrays.toString(arr));
    }

    // ── CORRECT WAY: Return karke change karo ──
    static int[] createDoubled(int[] arr) {
        int[] result = new int[arr.length];
        for (int i = 0; i < arr.length; i++) result[i] = arr[i] * 2;
        return result;
    }

    // ── SWAP karne ka SAHI TARIKA — using array ──
    static int[] swap(int a, int b) {
        return new int[]{b, a};  // naya array return karo
    }

    public static void main(String[] args) {

        System.out.println("=== CASE 1: Primitive Swap ===");
        int x = 10, y = 20;
        System.out.println("Before: x=" + x + ", y=" + y);
        trySwap(x, y);
        System.out.println("After:  x=" + x + ", y=" + y + "  ← UNCHANGED!");

        System.out.println("\n=== CASE 2: Array Modify ===");
        int[] nums = {1, 2, 3, 4, 5};
        System.out.println("Before: " + Arrays.toString(nums));
        doubleArray(nums);
        System.out.println("After:  " + Arrays.toString(nums) + "  ← CHANGED!");

        System.out.println("\n=== CASE 3: Object Reassign ===");
        int[] arr2 = {10, 20, 30};
        System.out.println("Before: " + Arrays.toString(arr2));
        tryReassign(arr2);
        System.out.println("After:  " + Arrays.toString(arr2) + "  ← UNCHANGED!");

        System.out.println("\n=== CORRECT: Return Approach ===");
        int[] original = {5, 10, 15};
        int[] doubled = createDoubled(original);
        System.out.println("Original: " + Arrays.toString(original));
        System.out.println("Doubled:  " + Arrays.toString(doubled));

        int[] swapped = swap(100, 200);
        System.out.println("\nswap(100,200) = [" + swapped[0] + "," + swapped[1] + "]");
    }
}
▶ Output
=== CASE 1: Primitive Swap === Before: x=10, y=20 Inside trySwap: a=20, b=10 After: x=10, y=20 ← UNCHANGED! === CASE 2: Array Modify === Before: [1, 2, 3, 4, 5] After: [2, 4, 6, 8, 10] ← CHANGED! === CASE 3: Object Reassign === Before: [10, 20, 30] Inside tryReassign: [100, 200, 300] After: [10, 20, 30] ← UNCHANGED! === CORRECT: Return Approach === Original: [5, 10, 15] Doubled: [10, 20, 30] swap(100,200) = [200,100]
06

Method Overloading

Same Name Different Signatures · Compile-Time Polymorphism · Rules · Ambiguity

📖 Theory — Overloading Deep Dive

Ek Naam, Alag Kaam — Compile-Time Polymorphism

Method Overloading matlab ek class mein same naam ke multiple methods likhna — lekin unke parameter list alag alag honi chahiye (type ya count ya order mein).

Compiler compile time pe decide karta hai kaunsa version call hoga — isliye ise compile-time polymorphism ya static binding bhi kehte hain.

Valid overloading ke ways:

  • Parameter count alag: add(int a) vs add(int a, int b)
  • Parameter type alag: add(int a, int b) vs add(double a, double b)
  • Parameter order alag: add(int a, double b) vs add(double a, int b)

Return type se overloading NAHI hotiint add(int a) aur double add(int a) compilation error denge. Compiler sirf return type se distinguish nahi kar sakta.

EX 6.1

Method Overloading — 5 Patterns with Rules

Real-world overloading — print, calculate, convert — sab same naam se alag data types handle karo.
import java.util.Arrays;

public class MethodOverloading {

    // ── 1. Count se overloading ──
    static int add(int a)                        { return a; }
    static int add(int a, int b)                { return a + b; }
    static int add(int a, int b, int c)        { return a + b + c; }
    static int add(int a, int b, int c, int d) { return a + b + c + d; }

    // ── 2. Type se overloading ──
    static double add(double a, double b)      { return a + b; }
    static long   add(long a, long b)          { return a + b; }
    static String add(String a, String b)      { return a + b; }  // String concatenation

    // ── 3. Order se overloading ──
    static String format(String label, int val) { return label + ": " + val; }
    static String format(int val, String label) { return val + " = " + label; }

    // ── 4. print() overloading — like System.out.println ──
    static void print(int n)      { System.out.println("int:    " + n); }
    static void print(double d)   { System.out.println("double: " + d); }
    static void print(String s)   { System.out.println("String: " + s); }
    static void print(boolean b)  { System.out.println("bool:   " + b); }
    static void print(int[] arr)  { System.out.println("array:  " + Arrays.toString(arr)); }

    // ── 5. max() overloading ──
    static int    max(int a, int b)       { return a > b ? a : b; }
    static double max(double a, double b) { return a > b ? a : b; }
    static int    max(int a, int b, int c){ return max(max(a, b), c); } // reuse!

    public static void main(String[] args) {
        System.out.println("=== add() overloads ===");
        System.out.println(add(5));
        System.out.println(add(3, 4));
        System.out.println(add(1, 2, 3));
        System.out.println(add(10, 20, 30, 40));
        System.out.println(add(1.5, 2.5));
        System.out.println(add("Hello, ", "World"));

        System.out.println("\n=== format() order overloads ===");
        System.out.println(format("Score", 95));
        System.out.println(format(95, "Score"));

        System.out.println("\n=== print() type overloads ===");
        print(42);
        print(3.14);
        print("Java");
        print(true);
        print(new int[]{1, 2, 3});

        System.out.println("\n=== max() overloads ===");
        System.out.println("max(3,7) = " + max(3, 7));
        System.out.println("max(1.5,2.7) = " + max(1.5, 2.7));
        System.out.println("max(5,3,8) = " + max(5, 3, 8));
    }
}
▶ Output
=== add() overloads === 5 7 6 100 4.0 Hello, World === format() order overloads === Score: 95 95 = Score === print() type overloads === int: 42 double: 3.14 String: Java bool: true array: [1, 2, 3] === max() overloads === max(3,7) = 7 max(1.5,2.7) = 2.7 max(5,3,8) = 8
07

Recursion — Deep Dive

Base Case · Recursive Case · Call Stack · Tail Recursion · Classic Problems

📖 Recursion Theory — Complete

Method Jo Khud Ko Call Kare — Recursion

Recursion tab hoti hai jab ek method apne aap ko call kare. Har recursive solution ke 2 parts hote hain:

  • Base Case: Wo condition jahan recursion rok jaata hai aur seedha answer return karta hai. Bina base case ke StackOverflowError!
  • Recursive Case: Problem ko smaller version mein reduce karke apne aap ko call karo.

Kab use karo: Problem naturally sub-problems mein divide ho jaati ho — Tree traversal, factorial, fibonacci, sorting (merge/quick), backtracking (maze solving). Kab avoid karo: jab simple loop se ho sake (better performance, no stack overhead).

Stack Overflow: Agar base case galat ho ya recursion terminate na ho, JVM ka call stack full ho jaata hai → StackOverflowError. Java ka default stack size ~512KB-1MB hota hai.

Recursion Flow — factorial(4)
CALL 1factorial(4)
4 × f(3)
CALL 2factorial(3)
3 × f(2)
CALL 3factorial(2)
2 × f(1)
BASEfactorial(1)
return 1
↑ Unwind: 1 → 2×1=2 → 3×2=6 → 4×6=24
EX 7.1

Recursion Classic Problems — 6 Examples with Tracing

Factorial, Fibonacci, Sum of digits, Power, String reverse, Binary search — sab recursive solutions with trace.
public class RecursionClassics {

    // ── 1. Factorial — n! = n × (n-1)! ──
    static long factorial(int n) {
        if (n <= 1) return 1;          // base case
        return n * factorial(n - 1);    // recursive case
    }

    // ── 2. Fibonacci — fib(n) = fib(n-1) + fib(n-2) ──
    static int fibonacci(int n) {
        if (n <= 1) return n;           // base: fib(0)=0, fib(1)=1
        return fibonacci(n-1) + fibonacci(n-2);
        // Note: O(2^n) — slow for large n! Memoization use karo
    }

    // ── 3. Sum of Digits — 123 → 1+2+3=6 ──
    static int sumOfDigits(int n) {
        n = Math.abs(n);                // negative handle
        if (n < 10) return n;           // single digit = base case
        return (n % 10) + sumOfDigits(n / 10);
    }

    // ── 4. Power — x^n ──
    static long power(long base, int exp) {
        if (exp == 0) return 1;           // x^0 = 1
        if (exp == 1) return base;        // x^1 = x
        if (exp % 2 == 0) {               // Fast exponentiation O(log n)
            long half = power(base, exp/2);
            return half * half;
        }
        return base * power(base, exp - 1);
    }

    // ── 5. String Reverse ──
    static String reverse(String s) {
        if (s.length() <= 1) return s;    // base: 0 or 1 char
        return reverse(s.substring(1)) + s.charAt(0);
    }

    // ── 6. GCD — Euclidean Algorithm ──
    static int gcd(int a, int b) {
        if (b == 0) return a;            // base case
        return gcd(b, a % b);            // gcd(48,18) = gcd(18,12) = gcd(12,6) = gcd(6,0) = 6
    }

    // ── 7. Print N to 1 then 1 to N — See Both Directions ──
    static void printBothWays(int n) {
        if (n == 0) { System.out.println("[midpoint]"); return; }
        System.out.println("Going down: " + n);
        printBothWays(n - 1);           // recursive call BEFORE and AFTER to show both
        System.out.println("Coming up: " + n);
    }

    public static void main(String[] args) {
        System.out.println("10! = " + factorial(10));
        System.out.println("Fib(0-9): ");
        for (int i = 0; i < 10; i++) System.out.print(fibonacci(i) + " ");
        System.out.println();
        System.out.println("sumOfDigits(9876) = " + sumOfDigits(9876));
        System.out.println("2^10 = " + power(2, 10));
        System.out.println("3^5  = " + power(3, 5));
        System.out.println("reverse(\"Java\") = " + reverse("Java"));
        System.out.println("gcd(48, 18) = " + gcd(48, 18));
        System.out.println("\nprintBothWays(3):");
        printBothWays(3);
    }
}
▶ Output
10! = 3628800 Fib(0-9): 0 1 1 2 3 5 8 13 21 34 sumOfDigits(9876) = 30 2^10 = 1024 3^5 = 243 reverse("Java") = avaJ gcd(48, 18) = 6 printBothWays(3): Going down: 3 Going down: 2 Going down: 1 [midpoint] Coming up: 1 Coming up: 2 Coming up: 3
08

Varargs — Variable Arguments

...syntax · Internally Array · Rules · Overloading with Varargs

📖 Theory — Varargs

Variable Number of Arguments — Flexible Methods

Varargs (variable arguments) Java 5 mein aaya. type... name syntax se ek method 0 se lekar infinite arguments accept kar sakta hai — internally ye ek array hai.

Rules:

  • Varargs hamesha parameter list mein last honi chahiye
  • Ek method mein sirf ek varargs ho sakti hai
  • Method mein varargs ko array ki tarah treat karo — nums.length, nums[i]
  • Aap array bhi pass kar sakte ho — sum(new int[]{1,2,3}) bhi valid hai

System.out.printf(String format, Object... args) aur String.format() dono varargs use karte hain — ye aapne daily use kiya hai without knowing!

EX 8.1

Varargs — Complete Guide with Real-World Examples

sum, max, print, format — sab varargs ke saath. Array bhi pass hota hai. Mixed params ke saath use.
import java.util.Arrays;

public class VarargsDemo {

    // ── Basic varargs ──
    static int sum(int... nums) {           // nums internally is int[]
        int total = 0;
        for (int n : nums) total += n;
        return total;
    }

    // ── max with varargs — at least 1 required ──
    static int max(int first, int... rest) {   // first is required, rest optional
        int m = first;
        for (int n : rest) if (n > m) m = n;
        return m;
    }

    // ── Mixed params: regular + varargs ──
    static void logMessage(String level, String... messages) {
        System.out.print("[" + level + "] ");
        for (String msg : messages) System.out.print(msg + " | ");
        System.out.println();
    }

    // ── String join with separator ──
    static String join(String sep, String... parts) {
        if (parts.length == 0) return "";
        StringBuilder sb = new StringBuilder(parts[0]);
        for (int i = 1; i < parts.length; i++) sb.append(sep).append(parts[i]);
        return sb.toString();
    }

    // ── Zero args allowed ──
    static void showCount(int... nums) {
        System.out.println("Count: " + nums.length + ", Array: " + Arrays.toString(nums));
    }

    public static void main(String[] args) {
        System.out.println("sum() = "       + sum());              // 0 args
        System.out.println("sum(5) = "      + sum(5));             // 1 arg
        System.out.println("sum(1,2,3) = " + sum(1, 2, 3));       // 3 args
        System.out.println("sum(1..5) = "  + sum(1, 2, 3, 4, 5)); // 5 args

        // Array bhi pass kar sakte ho
        int[] arr = {10, 20, 30};
        System.out.println("sum(array) = " + sum(arr));

        System.out.println("\nmax(5) = "        + max(5));
        System.out.println("max(3,7) = "      + max(3, 7));
        System.out.println("max(3,1,9,5) = " + max(3, 1, 9, 5));

        System.out.println();
        logMessage("INFO");
        logMessage("DEBUG", "Server started");
        logMessage("ERROR", "DB failed", "Port 5432", "Retrying...");

        System.out.println("\n" + join(", ", "Java", "Python", "Go"));
        System.out.println(join(" | ", "Admin", "User", "Guest"));

        System.out.println();
        showCount();
        showCount(1);
        showCount(1, 2, 3, 4, 5);
    }
}
▶ Output
sum() = 0 sum(5) = 5 sum(1,2,3) = 6 sum(1..5) = 15 sum(array) = 60 max(5) = 5 max(3,7) = 7 max(3,1,9,5) = 9 [INFO] [DEBUG] Server started | [ERROR] DB failed | Port 5432 | Retrying... | Java, Python, Go Admin | User | Guest Count: 0, Array: [] Count: 1, Array: [1] Count: 5, Array: [1, 2, 3, 4, 5]
09

Static vs Instance Methods

static keyword · this keyword · When to use What · Math class examples

📖 Theory

Static Methods — Object Ke Bina Call Karo

Static method class ka hissa hai, kisi object ka nahi. ClassName.methodName() se call hota hai. Koi this nahi hoti, koi instance variables access nahi hoti.

Instance method object ke saath kaam karta hai. Object ki state (instance variables) access karta hai. Object banane ke baad hi call hota hai.

Static kab use karo: Utility/helper methods jo object ki state pe depend nahi karte — Math calculations, String manipulation, validation, factory methods. Math.sqrt(), Arrays.sort(), Integer.parseInt() sab static hain.

Common Mistake: Static method ke andar non-static variable access karna → compilation error. "Non-static member cannot be referenced from a static context."

EX 9.1

Static vs Instance — Complete Comparison + Utility Class

BankAccount class mein instance methods aur ek MathUtils class mein static methods — dono ka proper use dikhao.
public class StaticVsInstance {

    // ════════════ STATIC UTILITY CLASS ════════════
    // Sab methods static — object ki zaroorat nahi
    // Use: MathUtils.circleArea(5) — seedha class se call
    static class MathUtils {
        static double circleArea(double r)       { return Math.PI * r * r; }
        static double hypotenuse(double a, double b){ return Math.sqrt(a*a + b*b); }
        static int    clamp(int val, int min, int max){ return Math.max(min, Math.min(max, val)); }
        static boolean isPerfectSquare(int n) {
            int sqrt = (int) Math.sqrt(n);
            return sqrt * sqrt == n;
        }
        static int    digitCount(int n)           { return String.valueOf(Math.abs(n)).length(); }
    }

    // ════════════ INSTANCE CLASS ════════════
    // Methods depend on object state (balance, owner)
    // Must create object: BankAccount acc = new BankAccount(...)
    static class BankAccount {
        String owner;
        double balance;

        BankAccount(String owner, double balance) {
            this.owner   = owner;
            this.balance = balance;
        }
        void deposit(double amt) {
            if (amt <= 0) { System.out.println("Invalid deposit!"); return; }
            balance += amt;
            System.out.printf("[%s] Deposited: ₹%.2f | Balance: ₹%.2f%n", owner, amt, balance);
        }
        void withdraw(double amt) {
            if (amt > balance) { System.out.println("Insufficient funds!"); return; }
            balance -= amt;
            System.out.printf("[%s] Withdrawn: ₹%.2f | Balance: ₹%.2f%n", owner, amt, balance);
        }
        String getStatement() {
            return String.format("Account[%s] Balance: ₹%.2f", owner, balance);
        }
        // static method inside instance class — allowed
        static String getBankName() { return "Java National Bank"; }
    }

    public static void main(String[] args) {
        // Static — no object needed
        System.out.println("=== Static Utility ===");
        System.out.printf("Circle area (r=7): %.4f%n",   MathUtils.circleArea(7));
        System.out.printf("Hypotenuse(3,4):   %.1f%n",    MathUtils.hypotenuse(3,4));
        System.out.println("clamp(150, 0, 100): "          + MathUtils.clamp(150, 0, 100));
        System.out.println("isPerfectSquare(49): "         + MathUtils.isPerfectSquare(49));
        System.out.println("digitCount(12345): "          + MathUtils.digitCount(12345));
        System.out.println("Bank: "                        + BankAccount.getBankName());

        // Instance — object chahiye
        System.out.println("\n=== Instance Methods ===");
        BankAccount rahul = new BankAccount("Rahul", 5000);
        BankAccount priya = new BankAccount("Priya", 10000);

        rahul.deposit(2000);
        rahul.withdraw(1500);
        priya.withdraw(20000);  // insufficient funds
        priya.deposit(5000);

        System.out.println(rahul.getStatement());
        System.out.println(priya.getStatement());
    }
}
▶ Output
=== Static Utility === Circle area (r=7): 153.9380 Hypotenuse(3,4): 5.0 clamp(150, 0, 100): 100 isPerfectSquare(49): true digitCount(12345): 5 Bank: Java National Bank === Instance Methods === [Rahul] Deposited: ₹2000.00 | Balance: ₹7000.00 [Rahul] Withdrawn: ₹1500.00 | Balance: ₹5500.00 Insufficient funds! [Priya] Deposited: ₹5000.00 | Balance: ₹15000.00 Account[Rahul] Balance: ₹5500.00 Account[Priya] Balance: ₹15000.00
EX 9.2

Math Class Methods — Built-in Static Methods

Java ka Math class sab static methods wala — sqrt, pow, floor, ceil, abs, min, max, random — sab ek jagah.
public class MathClassDemo {
    public static void main(String[] args) {

        // ── Basic Math ──
        System.out.println("abs(-42)     = " + Math.abs(-42));
        System.out.println("sqrt(144)    = " + Math.sqrt(144));
        System.out.println("pow(2,10)    = " + Math.pow(2, 10));
        System.out.println("cbrt(27)     = " + Math.cbrt(27));

        // ── Rounding ──
        System.out.println("\nfloor(3.7)   = " + Math.floor(3.7));
        System.out.println("ceil(3.2)    = " + Math.ceil(3.2));
        System.out.println("round(3.5)   = " + Math.round(3.5));
        System.out.println("round(3.4)   = " + Math.round(3.4));

        // ── Min/Max ──
        System.out.println("\nmin(8,3)     = " + Math.min(8, 3));
        System.out.println("max(8,3)     = " + Math.max(8, 3));

        // ── Log ──
        System.out.printf("%nlog(100)     = %.4f%n", Math.log10(100));
        System.out.printf("ln(Math.E)   = %.4f%n",  Math.log(Math.E));

        // ── Constants ──
        System.out.printf("%nMath.PI      = %.10f%n", Math.PI);
        System.out.printf("Math.E       = %.10f%n",  Math.E);

        // ── Random — 0.0 to 1.0 ──
        System.out.printf("%nrandom()     = %.4f%n",  Math.random());
        int dice = (int)(Math.random() * 6) + 1;  // 1 to 6 dice roll
        System.out.println("Dice roll    = " + dice);

        // ── signum — sign of a number ──
        System.out.println("\nsignum(-5)   = " + (int) Math.signum(-5));
        System.out.println("signum(0)    = " + (int) Math.signum(0));
        System.out.println("signum(7)    = " + (int) Math.signum(7));
    }
}
▶ Output
abs(-42) = 42 sqrt(144) = 12.0 pow(2,10) = 1024.0 cbrt(27) = 3.0 floor(3.7) = 3.0 ceil(3.2) = 4.0 round(3.5) = 4 round(3.4) = 3 min(8,3) = 3 max(8,3) = 8 log(100) = 2.0000 ln(Math.E) = 1.0000 Math.PI = 3.1415926536 Math.E = 2.7182818285 random() = 0.7431 (varies) Dice roll = 4 (varies) signum(-5) = -1 signum(0) = 0 signum(7) = 1
10

Practice Programs

Topic-wise Problems · Click to Reveal Solutions

📝

Set A — Basic Methods

Return types, parameters, void methods

1
Temperature Converter — Celsius ↔ Fahrenheit ↔ Kelvin Teen conversion methods banao. Main mein sab conversions call karo.
Return TypeMath
Formula: F = C×9/5+32 | K = C+273.15 | C = (F-32)×5/9
public class P1_TempConverter {

    static double celsiusToFahrenheit(double c) { return c * 9.0 / 5.0 + 32; }
    static double celsiusToKelvin(double c)     { return c + 273.15; }
    static double fahrenheitToCelsius(double f) { return (f - 32) * 5.0 / 9.0; }

    public static void main(String[] args) {
        double[] celsius = {0, 37, 100, -40};
        for (double c : celsius) {
            System.out.printf("%.1f°C → %.2f°F → %.2fK%n",
                c, celsiusToFahrenheit(c), celsiusToKelvin(c));
        }
        System.out.printf("\n98.6°F → %.2f°C%n", fahrenheitToCelsius(98.6));
    }
}
▶ Output
0.0°C → 32.00°F → 273.15K 37.0°C → 98.60°F → 310.15K 100.0°C → 212.00°F → 373.15K -40.0°C → -40.00°F → 233.15K 98.6°F → 37.00°C
2
String Methods — Count vowels, count words, isPalindrome, reverse 4 String utility methods banao — sab common interview questions hain.
StringUtility Methods
char[] + toCharArray() + StringBuilder use karo
public class P2_StringUtils {

    static int countVowels(String s) {
        int count = 0;
        for (char c : s.toLowerCase().toCharArray())
            if ("aeiou".indexOf(c) != -1) count++;
        return count;
    }

    static int countWords(String s) {
        s = s.trim();
        if (s.isEmpty()) return 0;
        return s.split("\\s+").length;
    }

    static boolean isPalindrome(String s) {
        s = s.toLowerCase().replaceAll("[^a-z0-9]", "");
        String rev = new StringBuilder(s).reverse().toString();
        return s.equals(rev);
    }

    static String reverseWords(String s) {
        String[] words = s.trim().split("\\s+");
        StringBuilder sb = new StringBuilder();
        for (int i = words.length-1; i >= 0; i--)
            sb.append(words[i]).append(" ");
        return sb.toString().trim();
    }

    public static void main(String[] args) {
        System.out.println("Vowels in 'Hello World': " + countVowels("Hello World"));
        System.out.println("Words in '  Java  is  fun  ': " + countWords("  Java  is  fun  "));
        System.out.println("'racecar' palindrome: " + isPalindrome("racecar"));
        System.out.println("'A man a plan a canal Panama': " + isPalindrome("A man a plan a canal Panama"));
        System.out.println("reverseWords: " + reverseWords("Hello Java World"));
    }
}
▶ Output
Vowels in 'Hello World': 3 Words in ' Java is fun ': 3 'racecar' palindrome: true 'A man a plan a canal Panama': true reverseWords: World Java Hello
3
Number Theory Methods — isPrime, nextPrime, primeFactors, isArmstrong 4 number methods — interviews mein ye classic hain. Clean code likho.
Number TheoryO(√n)
sqrt(n) tak check karo prime ke liye — O(√n). Armstrong: sum of cube of digits = number.
import java.util.*;
public class P3_NumberTheory {

    static boolean isPrime(int n) {
        if (n < 2) return false;
        if (n == 2) return true;
        if (n % 2 == 0) return false;
        for (int i = 3; i * i <= n; i += 2) if (n % i == 0) return false;
        return true;
    }

    static int nextPrime(int n) {
        n++;
        while (!isPrime(n)) n++;
        return n;
    }

    static List<Integer> primeFactors(int n) {
        List<Integer> factors = new ArrayList<>();
        for (int i = 2; i * i <= n; i++) {
            while (n % i == 0) { factors.add(i); n /= i; }
        }
        if (n > 1) factors.add(n);
        return factors;
    }

    static boolean isArmstrong(int n) {
        String s = String.valueOf(n);
        int digits = s.length(), sum = 0;
        for (char c : s.toCharArray())
            sum += (int) Math.pow(c - '0', digits);
        return sum == n;
    }

    public static void main(String[] args) {
        System.out.println("isPrime(17) = "       + isPrime(17));
        System.out.println("nextPrime(10) = "     + nextPrime(10));
        System.out.println("primeFactors(360) = " + primeFactors(360));
        System.out.println("isArmstrong(153) = " + isArmstrong(153));
        System.out.println("isArmstrong(370) = " + isArmstrong(370));
        System.out.println("isArmstrong(100) = " + isArmstrong(100));
    }
}
▶ Output
isPrime(17) = true nextPrime(10) = 11 primeFactors(360) = [2, 2, 2, 3, 3, 5] isArmstrong(153) = true isArmstrong(370) = true isArmstrong(100) = false
🧩

Set B — Overloading + Recursion

Multiple method versions aur recursive solutions

4
Overloaded Calculator — Same Method Name, Different Types calculate() method banao jo int, double, aur String ke saath alag alag kaam kare.
OverloadingPolymorphism
Same method name, alag return types aur parameter types
public class P4_OverloadCalc {

    static int    calculate(int a, int b, char op) {
        switch(op) {
            case '+': return a + b;
            case '-': return a - b;
            case '*': return a * b;
            case '/': return b != 0 ? a / b : 0;
            default:  return 0;
        }
    }

    static double calculate(double a, double b, char op) {
        switch(op) {
            case '+': return a + b;
            case '-': return a - b;
            case '*': return a * b;
            case '/': return b != 0 ? a / b : 0;
            default:  return 0;
        }
    }

    static String calculate(String a, String b, char op) {
        if (op == '+') return a + b;
        if (op == '-') return a.replace(b, "");
        return "Unsupported";
    }

    public static void main(String[] args) {
        System.out.println("int:    10 + 3 = " + calculate(10, 3, '+'));
        System.out.println("int:    10 / 3 = " + calculate(10, 3, '/'));
        System.out.printf( "double: 10.5 * 2.0 = %.1f%n", calculate(10.5, 2.0, '*'));
        System.out.println("String: 'Hello' + ' World' = " + calculate("Hello", " World", '+'));
    }
}
▶ Output
int: 10 + 3 = 13 int: 10 / 3 = 3 double: 10.5 * 2.0 = 21.0 String: 'Hello' + ' World' = Hello World
5
Recursive Programs — Tower of Hanoi + Count Digits + Flatten Number Tower of Hanoi ek classic recursion problem hai. Count digits bhi recursive karo.
RecursionClassic
Hanoi: move n-1 disks to aux, move largest to dest, move n-1 from aux to dest
public class P5_Recursion {

    static void hanoi(int n, String from, String to, String aux) {
        if (n == 0) return;
        hanoi(n - 1, from, aux, to);
        System.out.println("Move disk " + n + ": " + from + " → " + to);
        hanoi(n - 1, aux, to, from);
    }

    static int countDigits(int n) {
        n = Math.abs(n);
        if (n < 10) return 1;
        return 1 + countDigits(n / 10);
    }

    static boolean isSorted(int[] arr, int idx) {
        if (idx == arr.length - 1) return true;
        if (arr[idx] > arr[idx + 1]) return false;
        return isSorted(arr, idx + 1);
    }

    public static void main(String[] args) {
        System.out.println("=== Tower of Hanoi (3 disks) ===");
        hanoi(3, "A", "C", "B");
        System.out.println("Total moves = 2^n - 1 = " + ((1 << 3) - 1));

        System.out.println("\ncountDigits(12345) = " + countDigits(12345));
        System.out.println("countDigits(-99)   = " + countDigits(-99));

        System.out.println("\nisSorted([1,2,3,4]) = " + isSorted(new int[]{1,2,3,4}, 0));
        System.out.println("isSorted([1,3,2,4]) = " + isSorted(new int[]{1,3,2,4}, 0));
    }
}
▶ Output
=== Tower of Hanoi (3 disks) === Move disk 1: A → C Move disk 2: A → B Move disk 1: C → B Move disk 3: A → C Move disk 1: B → A Move disk 2: B → C Move disk 1: A → C Total moves = 2^n - 1 = 7 countDigits(12345) = 5 countDigits(-99) = 2 isSorted([1,2,3,4]) = true isSorted([1,3,2,4]) = false
6
Varargs Calculator — Dynamic Stats Ek method likho jo koi bhi number of integers le aur sum, min, max, range ek saath return kare via array.
VarargsArray Return
Varargs + array return = flexible stats calculator
public class P6_VarargsStats {

    // returns [sum, min, max, range]
    static int[] stats(int... nums) {
        if (nums.length == 0) return new int[]{0,0,0,0};
        int sum = 0, min = nums[0], max = nums[0];
        for (int n : nums) { sum += n; if(n < min) min=n; if(n > max) max=n; }
        return new int[]{sum, min, max, max - min};
    }

    static void printStats(String label, int... nums) {
        int[] s = stats(nums);
        System.out.printf("%s → Sum:%d  Min:%d  Max:%d  Range:%d  Avg:%.1f%n",
            label, s[0], s[1], s[2], s[3], (double)s[0]/Math.max(1,nums.length));
    }

    public static void main(String[] args) {
        printStats("[5]",             5);
        printStats("[3,7]",           3, 7);
        printStats("[1,2,3,4,5]",     1, 2, 3, 4, 5);
        printStats("[10,20,5,99,1]",  10, 20, 5, 99, 1);
    }
}
▶ Output
[5] → Sum:5 Min:5 Max:5 Range:0 Avg:5.0 [3,7] → Sum:10 Min:3 Max:7 Range:4 Avg:5.0 [1,2,3,4,5] → Sum:15 Min:1 Max:5 Range:4 Avg:3.0 [10,20,5,99,1]→ Sum:135 Min:1 Max:99 Range:98 Avg:27.0

⚠️ Common Mistakes — Methods Mein

Missing Return Statement: int getMax(int a, int b) { if (a > b) return a; } — agar b >= a ho to koi return nahi → compilation error! Hamesha sab branches cover karo ya end mein default return rakh do.
Primitive Swap Trap: swap(int a, int b) — primitives call by value hain! Method ke andar swap original variables change nahi karega. Ya to array use karo, ya return array/object.
⚠️
Static Context Error: Static method se non-static field access karna: static void show() { System.out.println(name); } — agar name instance variable hai to "Cannot make a static reference to the non-static field" error aayega.
⚠️
Overloading vs Overriding Confusion: Overloading = same class, same name, different params (compile-time). Overriding = parent-child classes, same signature (runtime). Dono alag concepts hain — interviews mein galti mat karo.
StackOverflowError in Recursion: Base case missing ya wrong hone se infinite recursion chalta hai → stack overflow. Hamesha base case pehle likho aur dry-run karo chhote input pe. factorial(0) ya factorial(-1) bhi test karo.
Best Practice — Method Size: Ek method ek kaam kare (Single Responsibility). 20-30 lines se zyada ho to method tod do. Naam se pata chalna chahiye kya karta hai — calculateMonthlyEMI() better hai than calc().
🎯
Varargs Rule: Varargs hamesha last parameter honi chahiye — void f(int... nums, String s) compilation error! Sahi: void f(String s, int... nums). Aur ek hi varargs allowed hai per method.