Skip to main content

Methods

βœ” Definition​

  • A method provides the functionality / operation / behavior of an object

Syntax of a Method​

[modifiers]<return Type><methodName>(params) {
// Method implementation
}

βœ” Notes:​

  • modifiers β†’ optional (public, private, static, etc.)
  • returnType β†’ mandatory
  • methodName β†’ mandatory
  • params β†’ optional

Types of Methods

  1. Instance Methods
  2. Static Methods

1) Instance Methods​

βœ” Methods defined inside a class without using static modifier

class Hello {

void m1() {
// instance method
}
}

2) Static Methods​

βœ” Methods defined inside a class using static modifier

class Hello {

static void m2() {
// static method
}
}

Example (Instance vs Static Method)

class Hello {

void m1() {}

static void m2() {}
}

Method Calls​

βœ” Using Object Reference​

Hello h=new Hello();
h.m1();// VALID (instance method)
h.m2();// VALID (static method)

Using Class Name​

Hello.m1();// INVALID (instance method)
Hello.m2();// VALID (static method)

βœ” Using Null Reference​

Hello h=null;
h.m1();// INVALID (instance method β†’ runtime error)
h.m2();// VALID (static method)

Key Rules

βœ” Instance Methods​

  • Must be called using object reference
  • Cannot be accessed using class name

βœ” Static Methods​

Can be called in 3 ways:

  1. Using class name

    Hello.m2();
  2. Using reference variable (even if null)

    Hello h=null;
    h.m2();
  3. Using object reference

    Hello h=new Hello();
    h.m2();

🧠 Important Concept

πŸ‘‰ Static methods belong to class, not object

πŸ‘‰ Instance methods belong to object


⚑ Interview Quick Points

βœ” Can we call static method using null reference?

πŸ‘‰ Yes

βœ” Can we call instance method using class name?

πŸ‘‰ No

βœ” Can static method be called using object?

πŸ‘‰ Yes (but not recommended)

Method Invocation Examples


Lab347.java​

class Lab347 {

public static void main(String[] args) {
Hello h = new Hello();
h.show();
}
}

class Hello {

void show() {
System.out.println("show()");
}
}

Output:​

show()

βœ” Instance method called using object β†’ Valid


Lab348.java​

class Lab348 {

public static void main(String[] args) {
Hello.show();
}
}

class Hello {

void show() {
System.out.println("show()");
}
}

Result:​

  • Compilation Error

βœ” Instance method cannot be called using class name


Lab349.java​

class Lab349 {

public static void main(String[] args) {
Hello h = null;
h.show();
}
}

class Hello {

void show() {
System.out.println("show()");
}
}

Result:​

  • Runtime Exception (NullPointerException)

βœ” Instance method needs object β†’ null reference fails


Lab350.java​

class Lab350 {

public static void main(String[] args) {
Hello.show();
}
}

class Hello {

static void show() {
System.out.println("show()");
}
}

Output:​

show()

βœ” Static method called using class name β†’ Valid


Lab351.java​

class Lab351 {

public static void main(String[] args) {
Hello h = null;
h.show();
}
}

class Hello {

static void show() {
System.out.println("show()");
}
}

Output:​

show()

βœ” Static method works even with null reference


Lab352.java​

class Lab352 {

public static void main(String[] args) {
Hello h = new Hello();
h.show();
}
}

class Hello {

static void show() {
System.out.println("show()");
}
}

Output:​

show()

βœ” Static method can be called using object (but not recommended)


Summary of Concepts

ScenarioResult
Instance method via objectValid
Instance method via class nameCompile error
Instance method via nullRuntime error
Static method via class nameValid
Static method via null referenceValid
Static method via objectValid

🧠 Important Understanding

πŸ‘‰ Instance method β†’ requires actual object

πŸ‘‰ Static method β†’ belongs to class, not object


⚑ Interview Traps

βœ” h.show() where h = null

  • Works only if method is static

βœ” ClassName.method()

  • Works only if method is static

Method Examples (Continuation)


Lab353.java​

class Lab353 {

public static void main(String[] args) {
Hello h = new Hello();
h.show();
}
}

class Hello {

int a;
static int b;

void show() {
System.out.println(a);
System.out.println(b);
}
}

Output:​

0
0

βœ” Instance method can access:

  • Instance variables (a)
  • Static variables (b)

Lab354.java​

class Lab354 {

public static void main(String[] args) {
Hello.show();
}
}

class Hello {

int a;
static int b;

static void show() {
System.out.println(a);
System.out.println(b);
}
}

Result:​

  • Compilation Error

βœ” Static method cannot access instance variable directly


Lab355.java​

class Lab355 {

public static void main(String[] args) {
Hello.show();
}
}

class Hello {

static int b;

static void show() {
System.out.println(b);
}
}

Output:​

0

βœ” Static method can access static variables


3.4.5.1 Methods Return Type


βœ” Key Concepts​

1) Method Execution Result​

  • When a method performs an operation:
    • It may or may not produce a result

2) Ways to Use Method Result​

βœ” Two ways:

  1. Use the result inside the method
  2. Return the result to the caller

3) Returning a Value​

πŸ‘‰ If you want to return a value:

  • You must specify a return type

Examples:

int
boolean
String

4) No Return Value​

πŸ‘‰ If you don’t want to return anything:

  • Use:
void

Key Rules Summary

βœ” Instance method β†’ can access both instance & static variables

βœ” Static method β†’ can access only static variables directly

βœ” Return type:

  • Required when returning value
  • void when nothing is returned

🧠 Interview Quick Points

πŸ‘‰ Can static method access instance variable?

No (without object)

πŸ‘‰ Can instance method access static variable?

βœ” Yes

πŸ‘‰ What is default value of int?

βœ” 0

πŸ‘‰ What if no return value?

βœ” Use void

Method Return Type – Examples


Lab356.java​

class Lab356 {

public static void main(String[] args) {
Student st = new Student();
st.show();
}
}

class Student {

show() {
// INVALID
System.out.println("show()");
}
}

Result:​

  • Compilation Error

βœ” Method must have a return type


Lab357.java​

class Lab357 {

public static void main(String[] args) {
Student st = new Student();
st.setAge(-12);
System.out.println(st.age);
}
}

class Student {

int age;

void setAge(int age) {
this.age = age;
}
}

Output:​

-12

βœ” void method β†’ does not return value

βœ” It updates instance variable


Lab358.java​

class Lab358 {

public static void main(String[] args) {
Student st = new Student();
st.setAge(-12);
System.out.println(st.age);
}
}

class Student {

int age = 18;

void setAge(int age) {
if (age < 18) return;
this.age = age;
}
}

Output:​

18

βœ” return; β†’ exits method early

βœ” Age remains unchanged


Lab359.java​

class Lab359 {

public static void main(String[] args) {
Student st = new Student();
st.setAge(-12);
System.out.println(st.age);
}
}

class Student {

int age = 18;

void setAge(int age) {
if (age < 18) return 0; // INVALID
this.age = age;
}
}

Result:​

  • Compilation Error

βœ” Cannot return value in void method


Lab360.java​

class Lab360 {

public static void main(String[] args) {
Hello h = new Hello();
int a = h.show(10);
System.out.println(a);
}
}

class Hello {

int show(int x) {
return x + 1;
}
}

Output:​

11

βœ” Method returns value β†’ assigned to variable


Lab361.java​

class Lab361 {

public static void main(String[] args) {
Hello h = new Hello();
System.out.println(h.show(10));
}
}

class Hello {

int show(int x) {
return x + 1;
}
}

Output:​

11

βœ” Returned value used directly


Key Concepts

βœ” Return Type Rules​

CaseResult
No return typeCompile error
void method with return;Valid
void method with return value;Error
Non-void method without returnError

βœ” return Statement​

  • return; β†’ exits method (void)
  • return value; β†’ returns value (non-void)

🧠 Interview Quick Points

πŸ‘‰ Is return type mandatory?

βœ” Yes

πŸ‘‰ Can void method return value?

No

πŸ‘‰ Can void method use return;?

βœ” Yes

πŸ‘‰ What happens if return missing in non-void method?

Compile error

Lab362.java​

class Lab362 {

public static void main(String[] args) {
Hello h = new Hello();
h.show(10);
System.out.println("Hello Guys");
}
}

class Hello {

int show(int x) {
return x + 1;
}
}

Output:​

Hello Guys

βœ” Return value is ignored

βœ” Method executes, but result not used


Lab363.java​

class Lab363 {

public static void main(String[] args) {
Hello h = new Hello();
System.out.println(h.show(10));
}
}

class Hello {

void show(int x) {
System.out.println("show()");
}
}

Result:​

  • Compilation Error

βœ” Cannot use void method inside println()


Lab364.java​

class Lab364 {

public static void main(String[] args) {
Hello h = new Hello();
h.show(10);
System.out.println("Hello Guys");
}
}

class Hello {

int show(int x) {
System.out.println("show()");
}
}

Result:​

  • Compilation Error

βœ” Missing return statement in non-void method


Lab365.java​

class Lab365 {

public static void main(String[] args) {
Hello h = new Hello();
h.show(10);
System.out.println("Hello Guys");
}
}

class Hello {

int show(int x) {
System.out.println("show()");
return;
}
}

Result:​

  • Compilation Error

βœ” Cannot use empty return in non-void method


Lab366.java​

class Lab366 {

public static void main(String[] args) {
Hello h = new Hello();
h.show(10);
System.out.println("Hello Guys");
}
}

class Hello {

int show(int x) {
System.out.println("show()");
return 12L;
}
}

Result:​

  • Compilation Error

βœ” Cannot return long (12L) for int method


Lab367.java​

class Lab367 {

public static void main(String[] args) {
Hello h = new Hello();
System.out.println(h.show(10));
}
}

class Hello {

long show(int x) {
System.out.println("show()");
return 'A';
}
}

Output:​

show()
65

βœ” 'A' β†’ converted to ASCII value β†’ 65

βœ” char can be promoted to long


Key Takeaways

βœ” Using Return Values​

  • You can ignore return value β†’ valid
  • You can use return value β†’ valid

βœ” Compile-Time Errors​

CaseReason
Using void in printlnNo return value
Missing return in non-voidMandatory
return; in non-voidInvalid
Wrong return typeType mismatch

βœ” Type Conversion Rules​

  • char β†’ can convert to int, long
  • long β†’ cannot convert to int (without cast)

🧠 Interview Quick Points

πŸ‘‰ Can you ignore a return value?

βœ” Yes

πŸ‘‰ Can void method be used in expression?

No

πŸ‘‰ Is return mandatory in non-void method?

βœ” Yes

πŸ‘‰ Can return type be different?

Must match (or be compatible)

Lab368.java​

class Lab368 {

public static void main(String[] args) {
Hello h = new Hello();
System.out.println(h.show(10));
}
}

class Hello {

long show(int x) {
System.out.println("show()");
return x + 1;
}
}

Output:​

show()
11

βœ” int β†’ automatically promoted to long


Lab369.java​

class Lab369 {

public static void main(String[] args) {
Hello h = new Hello();
System.out.println(h.show(10));
}
}

class Hello {

boolean show(int x) {
System.out.println("show()");
return true;
}
}

Output:​

show()
true

βœ” Boolean return works correctly


Lab370.java​

class Lab370 {

public static void main(String[] args) {
Hello h = new Hello();
System.out.println(h.show(10));
}
}

class Hello {

boolean show(int x) {
System.out.println("show()");
return 0;
}
}

Result:​

  • Compilation Error

βœ” Cannot return int for boolean


Lab371.java​

class Lab371 {

public static void main(String[] args) {
Hello h = new Hello();
System.out.println(h.show(10));
}
}

class Hello {

boolean show(int x) {
System.out.println("show()");
return false;
return false;
}
}

Result:​

  • Compilation Error

βœ” Unreachable code (second return never executes)


Lab372.java​

class Lab372 {

public static void main(String[] args) {
Hello h = new Hello();
System.out.println(h.isDigit('A'));
System.out.println(h.isDigit('8'));
}
}

class Hello {

boolean isDigit(char ch) {
System.out.println("isDigit(): " + ch);
boolean b = ch >= 48 && ch <= 57;
return b;
}
}

Output:​

isDigit(): A
false
isDigit(): 8
true

βœ” ASCII range check for digits (0–9 β†’ 48 to 57)


Lab373.java​

class Lab373 {

public static void main(String[] args) {
Hello h = new Hello();
System.out.println(h.isDigit('A'));
System.out.println(h.isDigit('8'));
}
}

class Hello {

boolean isDigit(char ch) {
System.out.println("isDigit(): " + ch);
if (ch >= 48 && ch <= 57) return true;
else return false;
}
}

Output:​

isDigit(): A
false
isDigit(): 8
true

βœ” Multiple return statements are allowed βœ” But only one executes per path


Key Takeaways

βœ” Return Type Rules​

  • Must match method return type
  • Implicit widening allowed (int β†’ long)
  • Not allowed: int β†’ boolean

βœ” Boolean Return​

  • Only true or false
  • Cannot use numeric values

βœ” Return Statements​

  • Multiple returns allowed βœ”
  • But unreachable code not allowed

βœ” Condition-Based Return​

Two styles:

return condition;

OR

if(condition) return true;
else return false;

🧠 Interview Quick Points

πŸ‘‰ Can int be returned in boolean method?

No

πŸ‘‰ Can we have multiple return statements?

βœ” Yes

πŸ‘‰ What is unreachable code?

Code after return

πŸ‘‰ Can int return into long?

βœ” Yes (widening)

3.4.5.2 Method Parameters

There are two types of arguments:​

  1. Formal Arguments
  2. Actual Arguments

Formal Arguments (Parameters)​

  • Arguments specified in the method definition/declaration
  • Also called Parameters

Example:​

void show(int a,int b) {
// a, b β†’ Formal Arguments
}

Actual Arguments​

  • Arguments specified in the method call

Example:​

Hello h=new Hello();
h.show(10,20);// 10, 20 β†’ Actual Arguments

Lab374.java​

class Lab374 {

public static void main(String[] args) {
Hello h = new Hello();
System.out.println(h.show());
}
}

class Hello {

int show(int x) {
System.out.println("show()");
return x + 1;
}
}

Result:​

  • Compilation Error

βœ” Method requires 1 parameter, but none provided


Lab375.java​

class Lab375 {

public static void main(String[] args) {
Hello h = new Hello();
System.out.println(h.show(10, 20));
}
}

class Hello {

int show(int x) {
System.out.println("show()");
return x + 1;
}
}

Result:​

  • Compilation Error

βœ” Method expects 1 argument, but 2 provided


Lab376.java​

class Lab376 {

public static void main(String[] args) {
Hello h = new Hello();
h.show(12);
}
}

class Hello {

void show(byte x) {
System.out.println("show(byte)");
}
}

Result:​

  • Compilation Error

βœ” int (12) cannot be passed to byte parameter directly

βœ” Requires explicit casting


Lab377.java​

class Lab377 {

public static void main(String[] args) {
Hello h = new Hello();
byte b = 12;
h.show(b);
}
}

class Hello {

void show(byte x) {
System.out.println("show(byte)");
}
}

Output:​

show(byte)

βœ” Correct type match (byte β†’ byte)


Key Takeaways

βœ” Argument Matching Rules​

  • Number of arguments must match
  • Type of arguments must match

βœ” Type Conversion​

CaseResult
byte β†’ intβœ” Allowed
int β†’ byteNot allowed (needs cast)

βœ” Errors You Must Remember​

  • Missing arguments
  • Extra arguments
  • Wrong data type

🧠 Interview Quick Points

πŸ‘‰ What are formal arguments?

βœ” Defined in method

πŸ‘‰ What are actual arguments?

βœ” Passed during method call

πŸ‘‰ Can int go into byte parameter?

No (needs casting)

πŸ‘‰ Must argument count match?

βœ” Yes

Lab378.java​

class Lab378 {

public static void main(String[] args) {
Hello h = new Hello();
h.show((byte) 12);
}
}

class Hello {

void show(byte x) {
System.out.println("show(byte)");
}
}

Output:​

show(byte)

βœ” Explicit type casting (int β†’ byte) works


Lab379.java​

class Lab379 {

public static void main(String[] args) {
Hello h = new Hello();
h.show(65);
}
}

class Hello {

void show(char x) {
System.out.println("show(char)");
}
}

Result:​

  • Compilation Error

βœ” int cannot be automatically converted to char


Lab380.java​

class Lab380 {

public static void main(String[] args) {
Hello h = new Hello();
h.show('A');
}
}

class Hello {

void show(char x) {
System.out.println("show(char)");
}
}

Output:​

show(char)

βœ” Direct char value works


Lab381.java​

class Lab381 {

public static void main(String[] args) {
Hello h = new Hello();
h.show((char) 65);
}
}

class Hello {

void show(char x) {
System.out.println("show(char)");
}
}

Output:​

show(char)

βœ” Explicit casting (int β†’ char) works


3.4.5.3 Method Overloading

Definition​

You can define multiple methods in the same class with the same name but different parameters.

πŸ‘‰ This is called METHOD OVERLOADING


Rules of Method Overloading​

βœ” Must:​

  • Method name should be same

βœ” Must change parameters:​

  1. Number of parameters
  2. Type of parameters
  3. Order of parameters

❗ Important:​

  • Return type alone is NOT enough to overload a method

Lab382.java​

class Lab382 {

public static void main(String[] args) {
Hello h = new Hello();
int a = h.add(10, 20);
System.out.println(a);
h.add(10, 20);
}
}

class Hello {

int add(int a, int b) {
System.out.println("add(int,int)");
return a + b;
}

void add(int a, int b) {
System.out.println("add(int,int)");
}
}

Result:​

  • Compilation Error

βœ” Duplicate method

βœ” Only return type is different β†’ NOT valid overloading


Key Takeaways

βœ” Type Casting​

CaseResult
int β†’ byte(needs cast)
int β†’ char(needs cast)
(byte) / (char) castingβœ” allowed

βœ” Method Overloading Rules​

  • Same method name βœ”
  • Different parameters βœ”
  • Only return type change

🧠 Interview Quick Points

πŸ‘‰ Can we overload methods with only return type?

No

πŸ‘‰ What defines method signature?

βœ” Method name + parameters

πŸ‘‰ Is casting required for narrowing?

βœ” Yes

πŸ‘‰ Is char compatible with int?

βœ” Only with explicit cast

Lab383.java​

class Lab383 {

public static void main(String[] args) {
Hello h = new Hello();

int a = h.add(10, 20);
System.out.println(a);

int b = h.add(10, 20, 30);
System.out.println(b);
}
}

class Hello {

int add(int a, int b) {
System.out.println("add(int,int)");
return a + b;
}

int add(int a, int b, int c) {
System.out.println("add(int,int,int)");
return a + b + c;
}
}

Output:​

add(int,int)
30
add(int,int,int)
60

βœ” Overloading by number of parameters


Lab384.java​

class Lab384 {

public static void main(String[] args) {
Hello h = new Hello();

int a = h.add(10, 20);
System.out.println(a);

String b = h.add("JavaWorld", 99);
System.out.println(b);
}
}

class Hello {

int add(int a, int b) {
System.out.println("add(int,int)");
return a + b;
}

String add(String a, int b) {
System.out.println("add(String,int)");
return a + b;
}
}

Output:​

add(int,int)
30
add(String,int)
JavaWorld99

βœ” Overloading by type of parameters


Lab385.java​

class Lab385 {

public static void main(String[] args) {
Hello h = new Hello();

String a = h.add(99, "JavaWorld");
System.out.println(a);

String b = h.add("JavaWorld", 99);
System.out.println(b);
}
}

class Hello {

String add(int b, String a) {
System.out.println("add(int,String)");
return a + b;
}

String add(String a, int b) {
System.out.println("add(String,int)");
return a + b;
}
}

Output:​

add(int,String)
JavaWorld99
add(String,int)
JavaWorld99

βœ” Overloading by order of parameters


Lab386.java​

class Lab386 {

public static void main(String[] args) {
Hello h = new Hello();

byte b = 20;
h.add(10, b);
h.add(b, b);
}
}

class Hello {

void add(int a, byte b) {
System.out.println("add(int,byte)");
}
}

Output:​

add(int,byte)
add(int,byte)

βœ” byte β†’ int (widening) works

βœ” Both calls resolve to same method


Lab387.java​

class Lab387 {

public static void main(String[] args) {
Hello h = new Hello();

byte b = 20;
h.add(b, 10);
h.add(b, b);
}
}

class Hello {

void add(byte a, int b) {
System.out.println("add(byte,int)");
}
}

Result:​

  • Compilation Error

βœ” h.add(b, b) fails

βœ” Because second byte cannot automatically match int in this context (no exact match)


Key Takeaways

βœ” Method Overloading Variations​

VariationExample
Number of paramsadd(a,b) vs add(a,b,c)
Type of paramsadd(int,int) vs add(String,int)
Order of paramsadd(int,String) vs add(String,int)

βœ” Type Conversion Priority​

  1. Exact match
  2. Widening (byte β†’ int)
  3. Otherwise β†’ Error

βœ” Important Rules​

  • Compiler chooses best match
  • Automatic widening works βœ”
  • Narrowing needs casting

🧠 Interview Quick Points

πŸ‘‰ How does Java choose overloaded method?

βœ” Best match (exact > widening)

πŸ‘‰ Can order change method signature?

βœ” Yes

πŸ‘‰ Is byte β†’ int allowed?

βœ” Yes

πŸ‘‰ Is int β†’ byte allowed automatically?

No

Lab388.java​

class Lab388 {

public static void main(String[] args) {
Hello h = new Hello();
byte b = 20;

h.add(b, 10);
h.add(10, b);
}
}

class Hello {

void add(byte a, int b) {
System.out.println("add(byte,int)");
}

void add(int a, byte b) {
System.out.println("add(int,byte)");
}
}

Output:​

add(byte,int)
add(int,byte)

βœ” Method selected based on parameter order & type


Lab389.java​

class Lab389 {

public static void main(String[] args) {
Hello h = new Hello();
byte b = 20;

h.add(b, b);
}
}

class Hello {

void add(byte a, int b) {
System.out.println("add(byte,int)");
}

void add(int a, byte b) {
System.out.println("add(int,byte)");
}
}

Result:​

  • Compilation Error (Ambiguity)

βœ” Both methods are possible after widening

βœ” Compiler cannot decide β†’ ambiguous call


Lab390.java​

class Lab390 {
public static void main(String[] args) {
Hello h=new Hello();

h.show(null);
h.show("JavaWorld");
h.show(h);
}
}

class Hello {
void show(String str) {
System.out.println("show(String)");
}

void show(Objectstr) {
System.out.println("show(Object)");
}
}

Output:​

show(String)
show(String)
show(Object)

βœ” String is more specific than Object

βœ” null prefers most specific reference type


Lab391.java​

class Lab391 {
public static void main(String[] args) {
Hello h=new Hello();

h.show("JavaWorld");
h.show(h);
}
}

class Hello {
void show(String str) {
System.out.println("show(String)");
}

void show(Hellostr) {
System.out.println("show(Hello)");
}
}

Output:​

show(String)
show(Hello)

βœ” Exact type match is chosen


Lab392.java​

class Lab392 {
public static void main(String[] args) {
Hello h=new Hello();

h.show(null);
}
}

class Hello {
void show(String str) {
System.out.println("show(String)");
}

void show(Hellostr) {
System.out.println("show(Hello)");
}
}

Result:​

  • Compilation Error (Ambiguity)

βœ” null matches both String and Hello

βœ” No clear "most specific" β†’ ambiguity


Key Takeaways

βœ” Ambiguity in Overloading​

Occurs when:

  • Multiple methods match equally well
  • Compiler cannot choose best method

βœ” Method Selection Priority​

  1. Exact match
  2. Most specific type
  3. Widening

βœ” Special Case: null​

ScenarioResult
String vs ObjectString chosen βœ”
Two unrelated typesAmbiguity

🧠 Interview Quick Points

πŸ‘‰ What is ambiguity in Java?

βœ” When compiler can't decide method

πŸ‘‰ Which is more specific: String or Object?

βœ” String

πŸ‘‰ What happens with null?

βœ” Chooses most specific OR gives error

πŸ‘‰ Can ambiguity happen with primitives?

βœ” Yes (due to widening)

3.4.5.4 Recursion

βœ” Recursion is the process of calling one method from itself.


Lab393.java​

class C {

void m3(int x) {
System.out.println("m3 Begins :" + x);
System.out.println("m3 Ends :" + x);
}
}

class B {

void m2(int x) {
System.out.println("m2 Begins :" + x);
new C().m3(x + 10);
System.out.println("m2 Ends :" + x);
}
}

class A {

void m1(int x) {
System.out.println("m1 Begins :" + x);
new B().m2(x + 10);
System.out.println("m1 Ends :" + x);
}
}

class Lab393 {

public static void main(String[] args) {
int x = 10;
System.out.println("main begins :" + x);
new A().m1(x + 10);
System.out.println("main ends :" + x);
}
}

Execution Flow (Call Stack Explanation)

Step-by-step calls:​

  1. main()

    x = 10
    calls m1(20)
  2. m1(20)

    calls m2(30)
  3. m2(30)

    calls m3(40)
  4. m3(40)

    executes and return s
  5. Control returns back:

    m3 β†’ m2 β†’ m1 β†’ main

🧾 Output

main begins :10
m1 Begins :20
m2 Begins :30
m3 Begins :40
m3 Ends :40
m2 Ends :30
m1 Ends :20
main ends :10

🧠 Call Stack Visualization

MethodValue of x
main10
m120
m230
m340

πŸ‘‰ Stack grows top-down (calls)

πŸ‘‰ Stack shrinks bottom-up (returns)


Key Concepts

βœ” Each method call creates a new stack frame

βœ” Execution is Last-In-First-Out (LIFO)

βœ” Control always returns to the caller

βœ” Recursion uses the same stack behavior


⚠️ Important Note

πŸ‘‰ This example shows method chaining, not true recursion

(True recursion = method calling itself)

Example of real recursion:

void m(int x) {
if (x == 0) return;
System.out.println(x);
m(x - 1);
}

Lab394.java​

class Hello {

void m1(int x) {
System.out.println("m1 Begins :" + x);
if (x != 0) m1(x / 10);
System.out.println("m1 Ends :" + x);
}
}

class Lab394 {

public static void main(String[] args) {
int x = 98;
System.out.println("main begins :" + x);
new Hello().m1(x);
System.out.println("main ends :" + x);
}
}

Execution Flow

Initial call:​

main β†’ m1(98)

Recursive calls:​

m1(98)
β†’ m1(9)
β†’ m1(0)

Return phase:​

m1(0) return s
m1(9) return s
m1(98) return s
main ends

🧾 Output

main begins :98
m1 Begins :98
m1 Begins :9
m1 Begins :0
m1 Ends :0
m1 Ends :9
m1 Ends :98
main ends :98

🧠 Stack Behavior

Call Stack (Top β†’ Bottom during execution)​

Method CallValue of x
m10
m19
m198
main98

βœ” Calls go downward (stack grows)

βœ” Returns go upward (stack shrinks)


Key Concept

βœ” Base Condition​

if (x!=0)
  • Stops recursion when x == 0

βœ” Recursive Step​

m1(x/10);
  • Reduces problem size (98 β†’ 9 β†’ 0)

⚠️ Important Note

πŸ‘‰ If the condition was missing:

m1(x/10);

It would cause StackOverflowError


πŸ’‘ Insight

This program:

  • Breaks a number digit by digit
  • Shows how recursion unwinds (reverse order execution)

Lab395.java​

class Hello {

long factorial(int n) {
if (n == 0 || n == 1) return 1;
else return n * factorial(n - 1);
}
}

class Lab395 {

public static void main(String[] args) {
Hello h = new Hello();
int n = 4;
long fac = h.factorial(n);
System.out.println("Factorial is : " + fac);
}
}

Execution Flow (Recursive Calls)

Calls:​

factorial(4)
β†’ 4 * factorial(3)
β†’ 3 * factorial(2)
β†’ 2 * factorial(1)
β†’ 1 (base case)

πŸ” Return Phase (Unwinding)

factorial(1) = 1
factorial(2) = 2 * 1 = 2
factorial(3) = 3 * 2 = 6
factorial(4) = 4 * 6 = 24

🧾 Output

Factorial is : 24

🧠 Call Stack Visualization

Call Leveln value
factorial4
factorial3
factorial2
factorial1

βœ” Stack grows while calling

βœ” Stack shrinks while returning


Key Concepts

βœ” Base Condition​

if (n==0||n==1)
return1;

βœ” Recursive Case​

return n*factorial(n-1);

⚠️ Important Notes

  • Without base condition β†’ StackOverflowError
  • Each recursive call creates a new stack frame
  • Execution follows LIFO (Last In First Out)

πŸ’‘ Insight

πŸ‘‰ This is a classic recursion problem used in:

  • Interviews
  • Algorithm design
  • Understanding stack behavior

3.4.5.5 Call by Value / Call by Reference


πŸ”Ή Call by Value​

βœ” When you invoke a method by passing primitive data types, it is called CALL BY VALUE.

βœ” In call by value:

  • Changes made inside the called method will NOT affect the original value in the caller method.

Lab396.java​
class Lab396 {

public static void main(String[] args) {
int a = 99;
Hello h = new Hello();

System.out.println("main begin : " + a);
h.m1(a);
System.out.println("main ends : " + a);
}
}

class Hello {

void m1(int a) {
System.out.println("m1 begin : " + a);
a = a + 10;
System.out.println("m1 ends : " + a);
}
}

Output​

main begin : 99
m1 begin : 99
m1 ends : 109
main ends : 99

πŸ‘‰ Original value not changed β†’ because of call by value


πŸ”Ή Call by Reference​

βœ” When you invoke a method by passing reference types (objects), it is called CALL BY REFERENCE (conceptually in Java).


βœ” Behavior:​

  1. Modifying object properties
    • Changes ARE reflected in caller
  2. Modifying reference itself
    • Changes ARE NOT reflected in caller

Lab397.java​
class Lab397 {
public static void main(String[] args) {
Hai hai=new Hai();
hai.a=99;

Hello hello=new Hello();

System.out.println("main begin : "+hai.a);
hello.m1(hai);
System.out.println("main ends : "+hai.a);
}
}

class Hello {
void m1(Haihai) {
System.out.println("m1 begin : "+hai.a);
hai.a=hai.a+10;
System.out.println("m1 ends : "+hai.a);
}
}

class Hai {
int a;
}


Output​

main begin : 99
m1 begin : 99
m1 ends : 109
main ends : 109

πŸ‘‰ Object property changed globally β†’ behaves like reference sharing


🧠 Important Interview Insight

πŸ‘‰ Java is strictly Call by Value

  • For primitives β†’ value copied
  • For objects β†’ reference value copied (not actual object)

βœ” That’s why:

  • You can modify object state
  • But cannot change the reference itself

Quick Comparison

FeatureCall by ValueCall by Reference (Java behavior)
Data TypePrimitiveObject
Value ChangeNot reflectedReflected
Reference ChangeNot applicableNot reflected

Lab398.java​

class Lab398 {
public static void main(String[] args) {
Hai hai=new Hai();
hai.a=99;

Hello hello=new Hello();

System.out.println("main begin : "+hai.a);
hello.m1(hai);
System.out.println("main ends : "+hai.a);
}
}

class Hello {
void m1(Haihai) {
System.out.println("m1 begin : "+hai.a);

hai=new Hai();// new object created
hai.a=hai.a+10;// default value 0 + 10 = 10

System.out.println("m1 ends : "+hai.a);
}
}

class Hai {
int a;
}


Output​

main begin : 99
m1 begin : 99
m1 ends : 10
main ends : 99

🧠 Concept Explained​

πŸ‘‰ Inside method:

hai=new Hai();
  • A new object is created
  • Reference is changed locally only

πŸ‘‰ So:

  • Original object in main() remains unchanged
  • Changes inside method are NOT reflected

βœ” This proves:

Java passes reference value (copy), not actual reference


πŸ”Ή 3.4.5.6 Var-Args (Variable Arguments)


βœ” What is Var-Args?​

  • Introduced in Java 5
  • Used when a method needs to accept multiple values of same type

πŸ” Before Var-Args (Traditional Approaches)​

1. Method Overloading​

class Hello {
void sum(int a,int b) { }
void sum(int a,int b,int c) { }
void sum(int a,int b,int c,int d) { }
}

2. Using Array​

class Hello {
void sum(int[]arr) { }
}

πŸ‘‰ These approaches become complex and less flexible


βœ” Using Var-Args​

βœ” Advantage:​

  • Accepts any number of arguments
  • Cleaner and flexible

🧾 Syntax​

<return Type><methodName>(<dataType>fixedArg,<dataType>...varArgs) {
// method body
}

Examples​

void sum(int...values) { }

void sum(String str,int...values) { }

Key Rules​

βœ” Var-args must be last parameter

βœ” Only one var-args allowed per method

βœ” Internally treated as an array


πŸ’‘ Example Usage​

void sum(int... values) {
int total = 0;
for (int v : values) {
total += v;
}
System.out.println(total);
}

Call:

sum(10,20);
sum(10,20,30,40);

⚠️ Important Insight

πŸ‘‰ Var-args = syntactic sugar over arrays

sum(1,2,3)

πŸ‘‰ internally becomes:

sum(new int[]{1,2,3})

Lab399.java​

class Lab399 {

public static void main(String[] args) {
Hello h = new Hello();
h.sum(12, 23);
}
}

class Hello {

void sum(int a, int b) {
System.out.println("-- sum(int,int) --");
System.out.println(a + b);
}
}

Output​

-- sum(int,int) --
35

Lab400.java​

class Lab400 {

public static void main(String[] args) {
Hello h = new Hello();
h.sum(12, 23);
h.sum(12, 32, 43);
}
}

class Hello {

void sum(int a, int b) {
System.out.println("-- sum(int,int) --");
System.out.println(a + b);
}

void sum(int a, int b, int c) {
System.out.println("-- sum(int,int,int) --");
System.out.println(a + b + c);
}
}

Lab401.java​

class Lab401 {

public static void main(String[] args) {
Hello h = new Hello();

h.sum(new int[0]);
h.sum(new int[] { 12, 34, 54 });
h.sum(new int[] { 10, 20, 50, 30 });

// Not allowed directly:
// h.sum(12, 34, 54);
// h.sum(10, 20, 50, 30);
}
}

class Hello {

void sum(int arr[]) {
System.out.println("-- sum(int[]) --");
System.out.println("Length : " + arr.length);

int s = 0;
for (int a : arr) {
s = s + a;
}

System.out.println("Sum is : " + s);
}
}

Lab402.java​

class Lab402 {

public static void main(String[] args) {
Hello h = new Hello();

h.sum(new int[0]);
h.sum(new int[] { 12, 34, 54 });
h.sum(new int[] { 10, 20, 50, 30 });

h.sum(); // allowed
h.sum(12, 34, 54); // allowed
h.sum(10, 20, 50, 30); // allowed
}
}

class Hello {

void sum(int... arr) {
System.out.println("-- sum(int...) --");
System.out.println("Length : " + arr.length);

int s = 0;
for (int a : arr) {
s = s + a;
}

System.out.println("Sum is : " + s);
}
}

🧠 Concept Summary

πŸ”Ή Array Parameter​

  • Must pass array explicitly
sum(new int[]{1,2,3});
  • Cannot pass values directly

πŸ”Ή Var-Args​

  • Flexible input
sum(1,2,3);
sum();
  • βœ” Accepts zero or more values
  • Internally treated as array

Key Differences

FeatureArray ParameterVar-Args
Syntaxint[] arrint... arr
Call styleNeed arrayDirect values allowed
FlexibilityLessMore
Zero argumentsNot allowedβœ” Allowed

πŸ’‘ Important Insight

πŸ‘‰ Var-args makes method calls cleaner and more readable

Instead of:

sum(new int[]{10,20,30});

You can write:

sum(10,20,30);

Lab403.java​

class Lab403 {

public static void main(String[] args) {
Hello h = new Hello();
h.show();
}
}

class Hello {

void show(int a, int... arr) {
System.out.println("\nshow(int,int...)");
}
}

Lab404.java​

class Lab404 {

public static void main(String[] args) {
Hello h = new Hello();
h.show(10);
h.show(10, 20);
h.show(10, 20, 30);
}
}

class Hello {

void show(int a, int... arr) {
System.out.println("\nshow(int,int...)");
}
}

Lab405.java​

class Lab405 {

public static void main(String[] args) {
Hello h = new Hello();
h.m1(); // Ambiguity
}
}

class Hello {

void m1(int... a) {
System.out.println("m1(int...)");
}

void m1(String... a) {
System.out.println("m1(String...)");
}
}

⚠️ Result:​

  • Compilation Error β†’ Ambiguous method call
  • Because no arguments β†’ both methods match

Lab406.java​

class Lab406 {

public static void main(String[] args) {
Hello h = new Hello();
h.show(10);
}
}

class Hello {

void show(int... arr1, int... arr2) {
// INVALID
System.out.println("\nshow(int...,int...)");
}
}

Rule:​

  • Only one var-args parameter allowed
  • It must be last parameter

Lab407.java​

class Lab407 {

public static void main(String[] args) {
Hello h = new Hello();
h.show(10);
}
}

class Hello {

void show(int... arr1) {
System.out.println("\nshow(int...)");
}

void show(int[] arr1) {
System.out.println("\nshow(int[])");
}
}

⚠️ Result:​

  • Compilation Error β†’ Duplicate method
  • Because:
    int... ≑int[]

🧠 Concept Summary

πŸ”Ή 1. Var-Args with Fixed Parameter​

void show(int a,int...arr)

βœ” First argument mandatory

βœ” Remaining optional


πŸ”Ή 2. Allowed Calls​

show(10);
show(10,20);
show(10,20,30);

πŸ”Ή 3. Ambiguity Problem​

m1(int...)
m1(String...)
m1();// ambiguous

πŸ”Ή 4. Restrictions​

  • Only one var-args allowed
  • Must be last parameter
  • Cannot overload with array of same type

Interview Tips

πŸ‘‰ int... is internally treated as int[]

πŸ‘‰ Var-args improves readability but can create ambiguity

πŸ‘‰ Always avoid overloading with multiple var-args

Lab408.java​

class Lab408 {

public static void main(String[] args) {
Hello h = new Hello();
h.show(10); // Cannot pass single int directly
}
}

class Hello {

void show(int[]... arr) {
System.out.println("\nshow(int[]...)");
}
}

Note:​

  • int[]... means var-args of arrays (2D concept)
  • You cannot pass a single int
  • You must pass arrays

Lab409.java​

class Lab409 {

public static void main(String[] args) {
Hello h = new Hello();
h.show();

int arr1[] = new int[] { 10 };
int arr2[] = new int[] { 20, 30, 12 };

h.show(arr1, arr2); // Valid
}
}

class Hello {

void show(int[]... arr) {
System.out.println("\nshow(int[]...)");
}
}

Valid Usage:​

  • Passing multiple arrays
  • Passing zero arguments also allowed