Parameters and return values

A method is useful only if you can hand it data and get an answer back. Parameters are the inputs, the return value is the output, and Java checks both strictly at compile time. You'll see how arguments are matched by position, how guard clauses return early, how to return several values in an array, and the three compile errors every beginner meets, and then practise with 12 problems.

Module 5 · Methods⏱ 22 minBeginner12 practice problems
1 The story

The discount that charged too much

Riya is adding a festival discount to the college bookshop's billing program. She writes discount(price, percent) and tests it: 10% off Rs 500 gives Rs 450. Then her friend calls it as discount(10, 500), and a Rs 500 book now costs minus Rs 40.

discount(double price, int percent) discount(500, 10) 50010 pricepercent Rs 450.0 discount(10, 500) 10500 pricepercent Rs -40.0 (compiles, still wrong) myphatshala.in
Riya

Sir, Java is so strict about types. Why didn't it stop him from swapping the numbers?

Arjun Sir

Because both are numbers, and 10 and 500 both fit. Java matches arguments to parameters by position and checks only that the types fit. It doesn't know which number you meant as the price.

Riya

So I should check bad inputs inside the method too?

Arjun Sir

Yes. Put a guard clause at the top: if the percent is outside 0 to 100, return early. Today you'll learn exactly how values go in and come out of a method, and what javac checks on both sides.

2 Definition

What are parameters and return values?

Formal definition (write this in exams)

A parameter (formal parameter) is a variable declared in a method's header that receives a value when the method is called. An argument (actual parameter) is the value supplied in the call. Arguments are evaluated left to right and assigned to parameters by position; their number must match and each must be assignable to the parameter's type. A method's return type declares the type of the single value it sends back with a return statement, or void if it returns nothing.

In simple words

Parameters are the empty slots in an order form. Arguments are what you write in the slots when you place an order. The return value is the parcel that comes back. The slots are filled in order, so writing the quantity in the price box gives a wrong order.

Words you'll meet in this lesson

ParameterThe variable in the header: price in discount(double price, …).
ArgumentThe value in the call: 500 in discount(500, 10).
Parameter listAll parameters in order, with types, separated by commas.
Return valueThe one value a method sends back to its caller.
Early returnLeaving a method before its last line, from inside an if or loop.
Guard clauseAn early check at the top that rejects bad input and returns.

The rules javac checks

CountSame number of arguments as parameters (for now; varargs in Lesson 5.6 relax this)
Order and typeMatched by position. Each argument must fit its parameter's type: int → double is fine (widening), double → int is not
NamesDon't matter. The caller's variable names have nothing to do with the parameter names
Return typeEvery return must give a value that fits the declared type
Every pathA non-void method must return on every possible path, or it's a compile error
One valueOnly one value comes back; to return several, return an array or an object

Exam tip: know the three compile errors by their exact words: missing return statement (some path doesn't return), unreachable statement (code after a return), and incompatible types (wrong type returned or passed, e.g. possible lossy conversion from double to int).

3 Types and ways to use it

What can go in, what can come out

Many parameters

emi(double p, double rate, int months)
Matched by position, each with its own type.

Order matters

One returned value

static boolean isAdult(int age)
Any type: int, double, boolean, String…

return value;

Several values in an array

static int[] minMax(int[] a)
Pack the answers into one array and return its reference.

return new int[]{…};

Guard clauses: handle the bad cases first

public class Main {
    static double discount(double price, int percent) {
        if (percent <= 0) {
            return price;              // guard: nothing to discount
        }
        return price - price * percent / 100;
    }

    public static void main(String[] args) {
        double a = discount(500, 10);
        double b = discount(800, 0);
        System.out.println(a + " " + b);
    }
}
450.0 800.0

The three compile errors around return

Codejavac saysFix
if (m >= 75) return "A"; else if (m >= 40) return "B"; and nothing aftermissing return statementAdd a final return for the remaining case
return n * 2;
System.out.println("done");
unreachable statementMove the print before the return, or delete it
static int avg(int a, int b) { return (a + b) / 2.0; }incompatible types: possible lossy conversion from double to intReturn type double, or cast deliberately
void check(…) { … return 1; }incompatible types: unexpected return valueA void method can only use return;
int x = printLine(); (a void method)incompatible types: void cannot be converted to intA void call has no value to store

Type-safe is not mistake-proof: if two parameters have compatible types, like (double price, int percent), swapped arguments still compile. Use clear parameter names, keep parameter lists short, and validate inputs with guard clauses.

4 Step by step

From call to returned value

  1. The caller evaluates the arguments

    double a = discount(400 + 100, 10);
    Each argument expression is calculated first, left to right: 400 + 100 becomes 500. Only the resulting values are passed.
  2. Values are copied into the parameters, by position

    static double discount(double price, int percent)
    A new frame is pushed. The 1st value goes to the 1st parameter, the 2nd to the 2nd. The int 500 is widened to 500.0 to fit double price. javac already checked at compile time that every argument fits.
  3. Guard clauses reject bad input

    if (percent <= 0) {
        return price;
    }
    A return ends the method immediately, wherever it appears. The lines below it don't run for this call.
  4. The main path computes and returns

    return price - price * percent / 100;
    The expression is evaluated, converted to the return type if needed (only widening is automatic), and handed to the caller. The method's frame is popped.
  5. The caller uses the value

    double a = discount(500, 10);   // a = 450.0
    In the caller, the call expression is replaced by the returned value. It can be stored, printed, or passed straight into another call. If you ignore it, it is simply thrown away.
5 See it happen

Values in, value out: both views

Left: the line running and its effect. Right: arguments landing in parameter slots, and the returned value going back to main.

Two calls to discount 6 steps
What you see double a = discount(500, 10); static double discount(double price, int percent) return price - price * percent / 100; double b = discount(800, 0); System.out.println(a + " " + b); // arguments: 500 and 10 // main waits for the result // price = 500.0 (widened) // percent = 10 // guard: 10 <= 0 is false // 500.0 - 500.0*10/100 // → 450.0 // a = 450.0 // guard: 0 <= 0 is true // return price → 800.0 // (last line skipped) 450.0 800.0 The call supplies two arguments. They fill the parameters in order. The guard passes; the formula runs. The result replaces the call. This time the guard returns early. Both results printed. myphatshala.in
Behind the screen Arguments (values) 50010 8000 discount frame pricepercent 500.010 800.00 frame popped returns 450.0 ↓ early return 800.0 ↓ main a: (waiting) a = 450.0 a = 450.0 b: (waiting) a = 450.0 b = 800.0 Only the values travel, not variables. Slot 1 ← value 1, slot 2 ← value 2. Parameters are ordinary locals of this frame. One value goes back; the frame disappears. A fresh frame; the guard returns at once. main holds both results. myphatshala.in
6 Real-world use

Parameters and returns in real systems

In real code, a method's header is a contract: what it needs, and what it promises to give back. Teams read headers far more often than bodies.

Watch it with an example: an EMI calculator

emi(60000, 12): the arguments are copied into the parameters, the method works with its own copies, and one value travels back with return.

Arguments in, return value out 5 steps
Animated example int monthly = emi(60000, 12); static int emi(int principal, int months) if (months <= 0) throw …; return principal / months; return 5000; int monthly = 5000; main() args: 60000, 12 monthly = ? monthly = 5000 emi() principal = 60000 months = 12 12 > 0 ✓ → 5000 60000 12 5000 copies go in guard clause checks the input first return sends ONE value back the emi frame is gone; only the result stays myphatshala.in

1. Guard clauses in payment and banking code

Transfer and withdrawal methods start with checks: amount positive, account active, balance sufficient, daily limit not crossed. Each failed check returns or rejects immediately, so the money-moving line runs only when everything is valid.

Transfer request→if (amount <= 0) return …→Safe debit
emi(p, rate, n)→ 10379.18

2. Calculators: EMI, tax, premium

Loan EMI, income tax and insurance premium calculators are methods with several parameters and one returned number. The same method serves the website, the mobile app and the bank officer's screen.

Amount, rate, tenure→emi(p, rate, months)→Monthly EMI
minmaxavg

3. Returning several results together

A report method may need to give back a count, a total and a maximum. Beginners return an array; production code returns an object or a record with named fields (Modules 6 and 14), so callers can't mix up the positions.

Day's orders→return new int[]{count, total, max}→Dashboard
error: incompatibletypes: possible lossyconversion

4. The compiler as a safety net

Because parameter and return types are checked at compile time, a whole class of bugs never reaches production: passing text where a number is needed, or forgetting to return a value on some path.

Wrong type→javac error→Fixed before release

Examples are simplified. Real financial code uses BigDecimal for money and named result objects instead of arrays.

7 Run the code

A weekly sales summary

public class Main {
    static int[] minMax(int[] values) {
        int min = values[0];
        int max = values[0];
        for (int v : values) {
            if (v < min) min = v;
            if (v > max) max = v;
        }
        return new int[]{min, max};
    }

    static double average(int[] values) {
        if (values.length == 0) {
            return 0;
        }
        int sum = 0;
        for (int v : values) {
            sum += v;
        }
        return (double) sum / values.length;
    }

    public static void main(String[] args) {
        int[] sales = {4200, 3900, 5100, 4700, 3600};
        int[] range = minMax(sales);
        System.out.println("Lowest day: Rs " + range[0]);
        System.out.println("Best day: Rs " + range[1]);
        System.out.println("Average: Rs " + average(sales));
        System.out.println("No sales yet: Rs " + average(new int[0]));
    }
}
Lowest day: Rs 3600 Best day: Rs 5100 Average: Rs 4300.0 No sales yet: Rs 0.0
  • static int[] minMax(int[] values)Takes an array, returns a new two-element array: index 0 = min, index 1 = max.
  • if (values.length == 0) return 0;A guard clause: avoids dividing by zero. The int 0 widens to 0.0 for the double return type.
  • (double) sum / values.lengthCast first so the average keeps its decimals (Lesson 2.4).
  • average(new int[0])An argument can be any expression of the right type, even a brand-new empty array.
8 Line by line

Splitting a bill: two values in one returned array

Watch the arguments land in split's frame by position, the guard clause pass, and an array come back to main.

Worked examples: real problems, solved and traced in memory

Three problems where what goes into a method and what comes out of it matter. Run each solution, then step through it to see arguments copied into parameters, early returns, and returned values (even arrays) arriving back in main.

Example 1Banking · ATM

Withdraw with guard clauses

Problem statement

Write withdraw(balance, amount) that returns the new balance. If the amount is not positive, or more than the balance, print a message and return the balance unchanged. Try a valid and an invalid withdrawal from Rs 5,000.

Input
balance = 5000
withdraw 2000, then withdraw 4000
Expected output
Insufficient funds
Balance: Rs 3000

Approach

  1. Check the bad cases first (guard clauses), each with its own early return.
  2. If both checks pass, the last line does the real work: return balance - amount.
  3. main stores the returned value back into its own balance; the method can't change main's variable directly.

Solution: run it live

What happens in memory, step by step

Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.

Example 2E-commerce · cart

Returning three numbers in one array

Problem statement

A cart page shows the number of items, the total amount and the costliest item. Write cartStats(int[] prices) that returns all three in one int[].

Input
prices = {499, 1299, 250}
Expected output
Items: 3
Total: Rs 2048
Costliest: Rs 1299

Approach

  1. A method has only one return value, so pack the three answers into an array: {count, total, max}.
  2. Loop once over the prices, updating total and max.
  3. Return a new array; main reads the values by index.

Solution: run it live

What happens in memory, step by step

Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.

Example 3Fintech · fixed deposits

Maturity amount: parameters in the right order

Problem statement

A bank app shows the maturity amount of a fixed deposit with simple interest. Write interest(principal, ratePercent, years) and maturity(principal, ratePercent, years), which uses it. Show a 2-year deposit of Rs 40,000 at 7%.

Input
principal = 40000, rate = 7%, years = 2
Expected output
Maturity amount: Rs 45600.0

Approach

  1. interest takes three parameters; the caller must pass them in the same order.
  2. maturity passes its own parameters straight on to interest and adds the principal.
  3. Watch the int argument 40000 arrive as 40000.0 in a double parameter (widening).

Solution: run it live

What happens in memory, step by step

Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.

9 Quiz and revision

Check yourself

Quick revision

Lesson 5.2 in one screen

  • Parameters are in the header; arguments are the values in the call.
  • Arguments are evaluated left to right and matched by position; names don't matter.
  • Count and types must fit: widening (int → double) is automatic, narrowing is a compile error.
  • A non-void method must return a value of its type on every path.
  • return ends the method at once; guard clauses use this to reject bad input early.
  • Only one value comes back; return an array (or object) for several.
  • Errors to recognise: missing return statement, unreachable statement, incompatible types.

Interview and viva questions

What is the difference between a parameter and an argument?

A parameter is the variable declared in the method header; it exists in the method's frame while the call runs. An argument is the actual value passed in a particular call. In square(5), 5 is the argument and n in square(int n) is the parameter.

Can a Java method return more than one value?

Not directly; a method has exactly one return value. To return several, return an array, a collection, or an object (a class or a record) whose fields hold the values. Objects are preferred because the fields have names.

What is a guard clause and why is it preferred over nested if-else?

A guard clause is an early check that handles an invalid or special case and returns immediately. It keeps the main logic at the left margin instead of buried in nested blocks, makes each rule easy to see, and ensures the main calculation only runs on valid input.

Why does javac report "missing return statement" when my if and else-if both return?

javac checks every possible path. If neither condition is true, execution reaches the end of the method without a return. Adding a final else or a last return covers that path. javac does not reason about which values are actually possible at run time.

Can a void method contain a return statement?

Yes, but only return; without a value, used to leave the method early. return 1; in a void method is a compile error: incompatible types: unexpected return value.

Practice problems

For each problem, first write only the method header: what goes in (parameters, in which order, of which types) and what comes out (the return type). Then fill in the body. The last three are real business tasks.

P1Easy

Simple interest

Write simpleInterest(double principal, double ratePercent, int years) that returns P × R × T / 100. Print the interest for two deposits.

Input
(50000, 7.5, 3) and (12000, 6, 2)
Expected output
Interest: Rs 11250.0
Interest: Rs 1440.0
Show solution and explanation
public class Main {
    static double simpleInterest(double principal, double ratePercent, int years) {
        return principal * ratePercent * years / 100;
    }

    public static void main(String[] args) {
        System.out.println("Interest: Rs " + simpleInterest(50000, 7.5, 3));
        System.out.println("Interest: Rs " + simpleInterest(12000, 6, 2));
    }
}
Interest: Rs 11250.0 Interest: Rs 1440.0

How it works: arguments are matched to parameters by position: the first goes to principal, the second to ratePercent, the third to years. The int arguments 50000 and 6 are widened to double automatically.

P2Easy

Power without Math.pow

Write power(int base, int exp) that returns baseexp as a long, using a loop.

Input
(2, 10), (5, 3), (7, 0)
Expected output
1024
125
1
Show solution and explanation
public class Main {
    static long power(int base, int exp) {
        long result = 1;
        for (int i = 1; i <= exp; i++) {
            result *= base;
        }
        return result;
    }

    public static void main(String[] args) {
        System.out.println(power(2, 10));
        System.out.println(power(5, 3));
        System.out.println(power(7, 0));
    }
}
1024 125 1

How it works: the result starts at 1 and is multiplied exp times. For exp = 0 the loop never runs and 1 is returned, which is correct. The return type is long because powers grow fast; an int would overflow sooner.

P3Easy

Is it a vowel?

Write isVowel(char ch) that returns true for a, e, i, o, u in either case. Test it on a few letters.

Input
'a', 'E', 'k', 'U'
Expected output
a -> true
E -> true
k -> false
U -> true
Show solution and explanation
public class Main {
    static boolean isVowel(char ch) {
        char c = Character.toLowerCase(ch);
        return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
    }

    public static void main(String[] args) {
        char[] letters = {'a', 'E', 'k', 'U'};
        for (char ch : letters) {
            System.out.println(ch + " -> " + isVowel(ch));
        }
    }
}
a -> true E -> true k -> false U -> true

How it works: converting to lowercase first halves the number of comparisons. The whole boolean expression is returned directly, so the method is one decision and one return.

P4Easy

Percentage with a guard

Write percentage(int obtained, int total) that returns the percentage as a double. If total is 0 or less, return 0 instead of dividing.

Input
(432, 500), (0, 0)
Expected output
86.4%
0.0%
Show solution and explanation
public class Main {
    static double percentage(int obtained, int total) {
        if (total <= 0) {
            return 0;
        }
        return obtained * 100.0 / total;
    }

    public static void main(String[] args) {
        System.out.println(percentage(432, 500) + "%");
        System.out.println(percentage(0, 0) + "%");
    }
}
86.4% 0.0%

How it works: the first if is a guard clause: it handles the bad case up front and leaves early, so the main formula below never sees a zero total. return 0; is allowed in a double method because 0 widens to 0.0.

P5Medium

Clamp a value into a range

Write clamp(int value, int min, int max) that returns min if value is below it, max if above it, otherwise the value itself. Use it to keep a volume level between 0 and 100.

Input
-20, 45, 130
Expected output
0
45
100
Show solution and explanation
public class Main {
    static int clamp(int value, int min, int max) {
        if (value < min) {
            return min;
        }
        if (value > max) {
            return max;
        }
        return value;
    }

    public static void main(String[] args) {
        System.out.println(clamp(-20, 0, 100));
        System.out.println(clamp(45, 0, 100));
        System.out.println(clamp(130, 0, 100));
    }
}
0 45 100

How it works: two guard clauses deal with the out-of-range cases; whatever reaches the last line is already valid. Note the parameter order (value, min, max): calling clamp(0, 100, 45) would compile but give a wrong answer, so order matters as much as type.

P6Medium

Return a reversed copy

Write reversed(int[] a) that returns a new array with the elements in reverse order, leaving the original unchanged.

Input
a = {10, 20, 30, 40}
Expected output
Original: [10, 20, 30, 40]
Reversed: [40, 30, 20, 10]
Show solution and explanation
import java.util.Arrays;

public class Main {
    static int[] reversed(int[] a) {
        int[] result = new int[a.length];
        for (int i = 0; i < a.length; i++) {
            result[i] = a[a.length - 1 - i];
        }
        return result;
    }

    public static void main(String[] args) {
        int[] a = {10, 20, 30, 40};
        int[] r = reversed(a);
        System.out.println("Original: " + Arrays.toString(a));
        System.out.println("Reversed: " + Arrays.toString(r));
    }
}
Original: [10, 20, 30, 40] Reversed: [40, 30, 20, 10]

How it works: the method creates a new array on the heap and returns its reference. The local variable result disappears when the method returns, but the array lives on because r in main now refers to it.

P7Medium

Count vowels in a String

Write countVowels(String text) that returns how many vowels the text contains. Reuse the idea from the isVowel problem.

Input
"Mumbai Indians", "Rhythm"
Expected output
6
0
Show solution and explanation
public class Main {
    static boolean isVowel(char ch) {
        return "aeiouAEIOU".indexOf(ch) >= 0;
    }

    static int countVowels(String text) {
        int count = 0;
        for (int i = 0; i < text.length(); i++) {
            if (isVowel(text.charAt(i))) {
                count++;
            }
        }
        return count;
    }

    public static void main(String[] args) {
        System.out.println(countVowels("Mumbai Indians"));
        System.out.println(countVowels("Rhythm"));
    }
}
6 0

How it works: countVowels calls isVowel once per character, passing a char argument to a char parameter. indexOf returns −1 when the character isn't in the list of vowels (Lesson 4.5).

P8Medium

Minimum and maximum in one call

A method can return only one value, but that value can be an array. Write minMax(int[] a) that returns {min, max}.

Input
marks = {67, 92, 48, 75, 88}
Expected output
Lowest: 48, Highest: 92
Show solution and explanation
public class Main {
    static int[] minMax(int[] a) {
        int min = a[0];
        int max = a[0];
        for (int x : a) {
            if (x < min) min = x;
            if (x > max) max = x;
        }
        return new int[]{min, max};
    }

    public static void main(String[] args) {
        int[] marks = {67, 92, 48, 75, 88};
        int[] result = minMax(marks);
        System.out.println("Lowest: " + result[0] + ", Highest: " + result[1]);
    }
}
Lowest: 48, Highest: 92

How it works: the two answers are packed into a small array and returned together. The caller must know the agreed order (index 0 = min, index 1 = max). Later you'll use a class or a record (Lesson 14.5) to give the values names.

P9Medium

Greatest common divisor

Write gcd(int a, int b) using Euclid's method: replace (a, b) with (b, a % b) until b is 0. Use it to simplify a fraction.

Input
fraction 84 / 126
Expected output
gcd = 42
84/126 = 2/3
Show solution and explanation
public class Main {
    static int gcd(int a, int b) {
        while (b != 0) {
            int r = a % b;
            a = b;
            b = r;
        }
        return a;
    }

    public static void main(String[] args) {
        int num = 84, den = 126;
        int g = gcd(num, den);
        System.out.println("gcd = " + g);
        System.out.println(num + "/" + den + " = " + (num / g) + "/" + (den / g));
    }
}
gcd = 42 84/126 = 2/3

How it works: inside the method, a and b are changed freely; they are copies, so num and den in main keep their values. 84, 126 → 126, 84 → 84, 42 → 42, 0, so the gcd is 42.

P10Business problem

Loan EMI calculator

Write emi(double principal, double annualRatePercent, int months) using EMI = P × r × (1 + r)n / ((1 + r)n − 1), where r is the monthly rate. Guard: if the rate is 0, the EMI is simply P / n. Print the EMI rounded to 2 decimals.

Input
Rs 5,00,000 at 9% for 60 months
Rs 60,000 at 0% for 12 months
Expected output
EMI: Rs 10379.18
EMI: Rs 5000.00
Show solution and explanation
public class Main {
    static double emi(double principal, double annualRatePercent, int months) {
        if (annualRatePercent == 0) {
            return principal / months;
        }
        double r = annualRatePercent / 12 / 100;
        double factor = Math.pow(1 + r, months);
        return principal * r * factor / (factor - 1);
    }

    public static void main(String[] args) {
        System.out.printf("EMI: Rs %.2f%n", emi(500000, 9, 60));
        System.out.printf("EMI: Rs %.2f%n", emi(60000, 0, 12));
    }
}
EMI: Rs 10379.18 EMI: Rs 5000.00

How it works:

  1. The guard clause handles the zero-interest offer separately; without it the formula would divide 0 by 0.
  2. (1 + r)n is computed once and stored in factor, then used twice.
  3. Three parameters of different meanings: passing months where the rate is expected would compile (int widens to double) but give nonsense, so read headers carefully.
P11Business problem

GST breakup for an invoice line

Write gstBreakup(double taxable, double gstPercent) that returns an array {cgst, sgst, total}. For an intra-state sale, CGST and SGST are each half of the GST.

Input
taxable = 2400, GST = 18%
Expected output
CGST 9%: Rs 216.0
SGST 9%: Rs 216.0
Invoice total: Rs 2832.0
Show solution and explanation
public class Main {
    static double[] gstBreakup(double taxable, double gstPercent) {
        double gst = taxable * gstPercent / 100;
        double cgst = gst / 2;
        double sgst = gst / 2;
        return new double[]{cgst, sgst, taxable + gst};
    }

    public static void main(String[] args) {
        double[] b = gstBreakup(2400, 18);
        System.out.println("CGST 9%: Rs " + b[0]);
        System.out.println("SGST 9%: Rs " + b[1]);
        System.out.println("Invoice total: Rs " + b[2]);
    }
}
CGST 9%: Rs 216.0 SGST 9%: Rs 216.0 Invoice total: Rs 2832.0

How it works:

  1. The method returns three related numbers in one double[].
  2. 18% of 2400 is 432, split equally into 216 + 216.
  3. Inter-state sales use IGST instead (the whole 18%); that would be a separate method or a third parameter.
P12Business problem

Railway fare with concessions

Write fare(int baseFare, int age): children under 5 travel free, passengers aged 60 or more get 40% off, everyone else pays the base fare. Use guard clauses and print the fare for a family.

Input
baseFare = 850, ages = {4, 34, 31, 63}
Expected output
Age 4: Rs 0
Age 34: Rs 850
Age 31: Rs 850
Age 63: Rs 510
Family total: Rs 2210
Show solution and explanation
public class Main {
    static int fare(int baseFare, int age) {
        if (age < 5) {
            return 0;
        }
        if (age >= 60) {
            return baseFare * 60 / 100;
        }
        return baseFare;
    }

    public static void main(String[] args) {
        int[] ages = {4, 34, 31, 63};
        int total = 0;
        for (int age : ages) {
            int f = fare(850, age);
            System.out.println("Age " + age + ": Rs " + f);
            total += f;
        }
        System.out.println("Family total: Rs " + total);
    }
}
Age 4: Rs 0 Age 34: Rs 850 Age 31: Rs 850 Age 63: Rs 510 Family total: Rs 2210

How it works:

  1. Each special case returns immediately, so the code reads as a list of rules, without nested if-else.
  2. 40% off means paying 60%: 850 × 60 / 100 = 510. Multiplying before dividing keeps the int arithmetic exact here.
  3. The order of arguments matters: swapping them as fare(34, 850) still compiles (both are int), but the method then treats 850 as the age and returns Rs 20.

Real-world scenario questions (asked in company interviews)

Most method bugs in real systems are about inputs that weren't checked and results that were misread. Decide your answer first, then open the model answer.

E-commerce · pricingFresher

A product sold at a negative price

A method applyDiscount(double price, int percent) is called from a new campaign screen, which keeps both values as int, as applyDiscount(percent, price). The code compiles and a Rs 1,200 jacket is shown at a negative price. Why didn't Java catch this, and how do you prevent it?

The interviewer is checking: do you know that arguments are matched by position, and that type-checking can't catch every mix-up?

Show a strong answer
  • Arguments are matched by position. The int percent widens to fit the double price parameter, and the int price fits the int percent parameter, so javac had nothing to complain about.
  • Add guard clauses: reject a percent outside 0–100 and a price that is not positive, with a clear error.
  • Make mix-ups harder: clear parameter names, fewer parameters, or a small object (e.g. a Discount type) instead of bare numbers.
  • Add a unit test with realistic values for the new screen.

Avoid: saying "the compiler should have caught it". Validation is the method's job.

Banking · transfers1–3 years

Deeply nested transfer code

A transfer method has five levels of nested if-else checking the amount, account status, KYC, balance and daily limit, with the actual debit buried in the middle. A bug slipped in where a blocked account could still transfer. How would you restructure it?

The interviewer is checking: can you use guard clauses and early returns to make validation obvious?

Show a strong answer
  • Rewrite each check as a guard clause at the top: if the condition fails, return a clear failure result (or reject) immediately.
  • After all guards, the debit and credit run at the left margin, only on the "everything is valid" path.
  • Each rule becomes one readable block that can be tested on its own, including the blocked-account case that was missed.
  • Keep the order intentional: cheap checks (amount > 0) first, costly ones (database lookups) later.

Avoid: adding a sixth nested level to fix the bug. The structure is what hid it.

Analytics · reportsFresher

The dashboard that swapped min and max

A helper returns int[]{min, max}. A teammate assumed index 0 was the maximum, so the dashboard showed "Best day: Rs 3,600" for months. How would you make this kind of bug less likely?

The interviewer is checking: do you see the weakness of returning unnamed values in an array?

Show a strong answer
  • Positions in an array carry no meaning; every caller must remember the order, and nothing checks it.
  • Return a small object or record with named fields, e.g. Range(int min, int max), so the caller writes range.max().
  • Or split into two clearly named methods, min(values) and max(values), if performance isn't an issue.
  • At minimum, document the order in the method comment and add a test.

Avoid: blaming the teammate. The method's design made the mistake easy.

Logistics · rate card1–3 years

"Just return 0 when something is wrong"

A method double shippingCharge(int pincode, double weightKg) returns 0 whenever the pincode is unknown or the weight is invalid. Finance later finds hundreds of orders shipped free by mistake. What would you change?

The interviewer is checking: do you understand that a return value must not hide errors?

Show a strong answer
  • 0 is a valid-looking charge, so callers can't tell "free delivery" from "something went wrong". The error was silently turned into a business decision.
  • For invalid input, fail clearly: throw an exception (Module 9) so the order can't be placed with a wrong charge.
  • For a legitimately "unknown" result, use a value the caller is forced to check, such as Optional (Lesson 14.4), rather than a magic number.
  • Log the bad pincodes so the rate card can be fixed.

Avoid: special return values like 0 or −1 for errors in money calculations.