Part 1: Varargs (Variable Arguments)
1️⃣ What is Varargs?
Varargs allows a method to accept any number of arguments.
Instead of writing multiple overloaded methods:
add(int a, int b)
add(int a, int b, int c)
add(int a, int b, int c, int d)We write:
add(int... numbers)2️⃣ Syntax
returnType methodName(datatype... variableName)Example:
public static int sum(int... numbers) {
int total = 0;
for (int num : numbers) {
total += num;
}
return total;
}Usage:
sum(10);
sum(10, 20);
sum(10, 20, 30, 40);3️⃣ What Happens Internally?
Very important 🔥
Varargs is actually converted into an array.
This:
sum(10, 20, 30);Internally becomes:
sum(new int[]{10, 20, 30});So:
int... numbersis actually:
int[] numbers4️⃣ Where is Varargs Used in Real Java?
Example:
System.out.println("Hello");This method belongs to:
Java Platform API Specification
Inside PrintStream, you’ll see:
printf(String format, Object... args)Notice: Object... args
This is why you can pass multiple values to printf().
5️⃣ Rules of Varargs
✅ Rule 1: Only one varargs parameter allowed
void test(int... a, int... b) ❌✅ Rule 2: Must be the last parameter
void test(int... a, String name) ❌
void test(String name, int... a) ✅6️⃣ Varargs + Overloading Confusion
Example:
void show(int a)
void show(int... a)Calling:
show(10);Java chooses the most specific method → show(int a)
Why? Because compiler prefers exact match over varargs.
This is part of Java’s overload resolution mechanism defined in the:
Java Language Specification
7️⃣ Performance Consideration
Each varargs call creates an array.
So:
sum(1,2,3);Creates a new array every time.
In tight loops → performance cost.
📌 Part 2: Autoboxing
Now let’s move to something more powerful.
1️⃣ What is Autoboxing?
Autoboxing = Automatic conversion of:
Primitive → Wrapper class
Example:
int x = 10;
Integer obj = x; // AutoboxingCompiler converts it to:
Integer obj = Integer.valueOf(x);2️⃣ What is Unboxing?
Wrapper → Primitive
Integer obj = 20;
int x = obj; // UnboxingConverted to:
int x = obj.intValue();3️⃣ Why Does Autoboxing Exist?
Because Java Collections work only with Objects.
Get Enginneringjava’s stories in your inbox
Join Medium for free to get updates from this writer.
Example:
ArrayList<int> ❌
ArrayList<Integer> ✅Collections are defined in:
Java Platform API Specification
So when you write:
ArrayList<Integer> list = new ArrayList<>();
list.add(10);Internally:
list.add(Integer.valueOf(10));5️⃣ Integer Caching (Very Important 🔥)
This is a tricky interview concept.
Integer a = 100;
Integer b = 100;System.out.println(a == b); // trueBut:
Integer a = 200;
Integer b = 200;System.out.println(a == b); // falseWhy?
Because Java caches integers from:
-128 to 127
Inside the Integer class cache.
So:
Integer.valueOf(100)Returns same cached object.
But:
Integer.valueOf(200)Creates new object.
This behavior is defined inside:
Java Language Specification
6️⃣ Autoboxing Pitfall — NullPointerException
Integer x = null;
int y = x; // ❌ Runtime errorUnboxing tries to call:
x.intValue();But x is null → NullPointerException.
7️⃣ Performance Issue with Autoboxing
This loop:
Integer sum = 0;
for(int i = 0; i < 1000000; i++) {
sum += i;
}Creates many temporary Integer objects.
Better:
int sum = 0;Use primitives for performance-critical code.
📌 Varargs + Autoboxing Together
Example:
void printAll(Integer... numbers)Calling:
printAll(1, 2, 3);What happens?
- Each int → autoboxed to Integer
- Then packed into Integer[]
So multiple conversions happen.
📌 Memory Perspective (JVM Understanding)
Primitives → stored in Stack
Wrapper Objects → stored in Heap
So autoboxing increases heap usage.
This connects directly to your earlier question about JVM data areas.
📌 Real-World Usage
You see varargs and autoboxing everywhere in:
- Logging frameworks
printf- Collections
- Stream API
- Lambda expressions
Modern Java (like in Spring Boot) heavily depends on these features.





