The distinction is simple once you see where each name lives. A parameter is declared in the method signature and exists only while that method runs. An argument is the value you supply at the call site. In getArea(width, height), width and height are parameters; whatever you write in the parentheses at the call is the argument. Students sometimes swap the two words, but the error is harmless as long as you know which is which. The part that changes how you write code is what happens to that argument on the way in. Java is strictly pass by value, so every argument arrives as a copy. Change a primitive parameter and the caller never notices. Pass an object or an array and you are copying a reference, so mutations to the contents are visible to the caller. Reassigning the parameter is invisible either way. That asymmetry is the source of most “my method changed nothing” bugs. Java also lets you accept any number of arguments with varargs, written Type... name. The compiler wraps whatever you pass into an array for you. It is genuinely convenient for logging and formatting helpers, though it is worth knowing it has a cost: because it always allocates an array, a varargs method in a hot loop is measurably slower than one taking a real array.
Detailed Explanation & Mechanics
1) Parameters and Arguments
A parameter is a variable declared in the signature. An argument is a value supplied at the call. They are two sides of the same operation.
// DECLARATION: width and height are FORMAL PARAMETERS
public static int getArea(int width, int height) {
return width * height;
}// CALL: 5 and 7 are ACTUAL ARGUMENTS
int area = getArea(5, HEIGHT);
Parameters are declared once in the signature. Arguments arrive at every call, and may differ each time.
Terms you will meet in textbooks: formal parameters means the declared names, actual parameters or arguments means the supplied values. They are the same two ideas under longer names, so if a book seems to contradict this page, it is almost certainly using a different word for the same slot.
2) Arguments Are Matched by Position, Not by Name
Java has no named arguments. The first argument fills the first parameter, the second fills the second, and the compiler checks the types in order.
final int WIDTH = 5;
final int HEIGHT = 7;
getArea(WIDTH, HEIGHT);
// width is 5, height is 7
getArea(HEIGHT, WIDTH);
// width is 7, height is 5, same result here
Because of that, two parameters of the same type are easy to swap by accident and hard to notice, especially when both are the same primitive. drawBox(width, height) called as drawBox(HEIGHT, WIDTH) compiles happily and looks right in a square. Grouping related values into a small object removes the whole class of bug, which is why parameter objects are such a common refactoring.
3) Every Type a Method Can Accept
What you pass
Declared as
Notes
A primitive
int, double, boolean
A copy of the value is made.
An object
String, Scanner, a class of yours
A copy of the reference is made.
An array
int[], String[]
Also a reference copy, so contents are shared.
Any number of values
int... values
Compiler builds an array for you.
A fixed count of any type
Type[] values
The general form varargs compiles to.
One subtlety catches everyone: an int argument can be widened automatically to a long or a double, but a double passed to an int parameter is a compile error. Narrowing needs an explicit cast, and silently losing the decimal part is usually a bug rather than an intention.
4) Pass by Value in Practice
This is the single most tested idea in methods, so it is worth being exact about. Java passes by value, always. What varies is whether the value being copied is a number or a reference.
public static void tryToChange(int number) {
number = 99;
// changes the local copy only
}public static void tryToChangeArray(int[] values) {
values[0] = 99;
// the caller DOES see this
values = new int[VALUES];
// the caller does NOT see this
}
Primitives are copied, so changes vanish. Objects share one underlying instance, so changes to contents show through.
This is why so many Java methods return a value instead of mutating a parameter. The caller passes in, gets nothing back, and quietly carries on with the old value. Returning the result makes the change impossible to miss.
Note the difference in tryToChangeArray. Writing values[0] modifies the shared array. Writing values points the local name at a different array, which only the method can see. The two lines look similar and mean very different things.
5) Parameters Are Local to the Method
A parameter behaves like any other local variable. It exists from the moment the method is entered until it returns, and nothing outside can see or touch it.
public static int shadow(int value) {
int doubled = value * 2;
return doubled;
// the parameter is gone once this ends
}int value = 10;
int result = shadow(value);
// the value held by the caller is intact
This scoping is a feature, not a limitation. Two methods can both use a variable called index without any interference, and no caller can accidentally modify another method’s working state.
6) Varargs, the Any Number Option
When the number of values is genuinely unknown, add three dots. The compiler gathers the arguments into an array before entering the body.
public static int sum(int... values) {
int total = 0;
for (int value : values) {
total = total + value;
} return total;
}final int A = 1;
final int B = 2;
final int C = 3;
final int D = 5;
sum(A, B, C);
// 6
sum(D);
// 5
sum();
// 0, an empty array
Inside the method, values is simply a int[], so you can iterate it, index it, or pass it on to another varargs method.
Rule
Detail
Must be the last parameter
Nothing may follow it, so the compiler knows where the list ends.
Only one per method
Two varargs parameters would be ambiguous.
Zero arguments is legal
sum() passes an empty array.
Can be passed to another varargs method
sum(more(...)) forwards the whole array.
Always allocates an array
Even a single argument builds a one element array.
Caller position is restricted
It must be last at the call site too, or the values are collected into an array.
Varargs is a good fit for logging, formatting, and test helpers, where the count varies. It is a poor fit for a hot loop, because the implicit array allocation happens on every call and shows up in profiling. In performance-sensitive code, take a real array instead.
7) Final Parameters
A parameter declared final cannot be reassigned inside the method. The reference cannot be pointed somewhere new, although the object it points at can still be modified.
public static String describe(final String name, final int count) {
name = "changed";
// compile error, the parameter is final
return name + count;
}public static void grow(final List<String> items) {
items.add("new");
// allowed, the list contents can change
items = new ArrayList<>();
// compile error
}
For a primitive final parameter, final and immutability are the same thing. For a reference, final only freezes the name, not the data, which is the distinction people most often miss.
8) Choosing a Good Parameter List
Three habits keep signatures readable.
Name them for meaning, not type.calculateTax(amount, rate) reads clearly. calculateTax(double, double) does not, and the compiler will not help you if you swap them.
Keep the count low. Beyond three or four, the likelihood of swapping two arguments climbs sharply. Grouping related values into a small record or class fixes both the ordering risk and the documentation problem at once.
Do not return one parameter unchanged. A method that takes a value and hands back the same value is doing nothing, and the caller is better off keeping it.
Grouping related parameters removes the chance of swapping two arguments of the same type.
9) Common Mistakes
Mistake
Symptom
Fix
Expecting a changed parameter to persist
Caller sees the old value
Return the result instead.
Swapping two same-type arguments
Wrong results, no compile error
Group them into one object.
Passing a double to an int parameter
Compile error
Cast explicitly if the loss is intended.
Something after a varargs parameter
Compile error
Move varargs to the end.
Two varargs in one method
Compile error
Take an array for one of them.
Assuming final freezes an object
Contents still change
It freezes the name, not the data.
Varargs in a hot loop
Unnecessary array allocation
Take a real array instead.
Null passed to a varargs parameter
NullPointerException when used
Check it, or overload with a single value.
Eight parameter mistakes. The compiler catches the fourth and fifth, which leaves seven for review to find.
Frequently Asked Questions
What is the difference between a parameter and an argument?
A parameter is a variable declared in the method signature, such as width in getArea(int width, int height). An argument is the value supplied at the call site, such as the 5 in getArea(5, height). The terms formal parameter and actual argument mean the same two things.
Does Java pass arguments by value or by reference?
Always by value, with no exceptions. What varies is what the value is: for a primitive it is the number itself, so changes are lost, while for an object it is the reference, so both sides still point at the same object and changes to its contents are shared.
Why does changing a parameter not update my variable?
Because the method received a copy. Java is pass by value, so reassigning the parameter only changes the copy the method is holding. The fix is either to return the new value or, for an object, to modify its contents rather than rebind the name.
What is varargs in Java?
A parameter declared with three dots, such as int... values, that accepts any number of arguments including none. The compiler collects them into an array before the method body runs, so inside the method values is simply an int array. It must be the last parameter.
Can a varargs parameter be followed by another parameter?
No. The varargs parameter must come last, because the compiler would otherwise have no way to know where the variable-length list ends. Putting another parameter after it is a compile error.
Does a final parameter make an object immutable?
No. It stops the reference being pointed at a different object, but the object it points at can still be modified. For a primitive parameter final and immutable are effectively the same thing, since there is no separate object to change.
How many parameters should a method take?
As few as possible, and past about three or four the risk of swapping two arguments of the same type rises sharply. Grouping related values into a small object or record removes that risk and makes the call site read better.
Can I pass an int where a double is expected?
Yes, that direction is safe because of automatic widening, and the int is promoted. The reverse is a compile error, because narrowing could lose the decimal part, so it needs an explicit cast and should only be used when that loss is genuinely intended.
// Demonstrates parameters, arguments, pass by value, and varargs.
public class ParameterDemo {
private static final int VALUE_NINETY_NINE = 99;
private static final int VALUES_COUNT = 3;
private static final int FIRST = 0;
private static final int WIDTH = 5;
private static final int HEIGHT = 7;
private static final int SAMPLE = 5;
private static final int STEP = 1;
// width and height are FORMAL PARAMETERS
public static int getArea(int width, int height) {
return width * height;
} // 1) PRIMITIVES ARE PASSED BY VALUE, SO THE CALLER SEES NOTHING
public static void tryToChange(int number) {
number = VALUE_NINETY_NINE;
// only the local copy changes
System.out.println(" inside tryToChange, number = " + number);
} // 2) OBJECTS AND ARRAYS SHARE THEIR CONTENTS
public static void tryToChangeArray(int[] values) {
values[FIRST] = VALUE_NINETY_NINE;
// the caller DOES see this
values = new int[VALUES_COUNT];
// the caller does NOT see this
} // 3) RETURNING IS THE RELIABLE WAY TO REPORT A CHANGE
public static int incremented(int number) {
return number + STEP;
} // 4) VARARGS ACCEPTS ANY NUMBER OF ARGUMENTS
public static int sum(int... values) {
int total = 0;
for (int value : values) {
total = total + value;
} return total;
} // VARARGS MUST BE THE LAST PARAMETER
public static String label(String prefix, int... values) {
return prefix + values.length;
} // 5) A final PRIMITIVE CANNOT BE REASSIGNED
public static int useFinal(final int amount) {
// amount = VALUE_NINETY_NINE; // this line would not compile
return amount * 2;
} // 6) A final REFERENCE FREEZES THE NAME, NOT THE DATA
public static void grow(final java.util.List<String> items) {
items.add("added");
// allowed, the contents can change
// items = new java.util.ArrayList<>(); // this would not compile
} public static void main(String[] args) {
int number = SAMPLE;
int[] numbers = {
1, 2, 3
};
// 5 and 7 are ACTUAL ARGUMENTS
System.out.println("getArea(5, 7) = " + getArea(WIDTH, HEIGHT));
System.out.println("label(\"n=\", 1,2,3) = " + label("n=", 1, 2, 3));
// 1) THE CALLER KEEPS THE ORIGINAL VALUE
System.out.println("before, number = " + number);
tryToChange(number);
System.out.println("after, number = " + number);
System.out.println("incremented() = " + incremented(number));
// 2) THE ARRAY CONTENTS ARE SHARED
tryToChangeArray(numbers);
System.out.println("after array call, first = " + numbers[FIRST]);
// 4) VARARGS, INCLUDING ZERO ARGUMENTS
System.out.println("sum(1, 2, 3) = " + sum(1, 2, 3));
System.out.println("sum(5) = " + sum(SAMPLE));
System.out.println("sum() = " + sum());
// 5) final PARAMETERS
System.out.println("useFinal(5) = " + useFinal(SAMPLE));
// 6) final REFERENCES STILL ALLOW MUTATION
java.util.List<String> items = new java.util.ArrayList<>();
items.add("first");
grow(items);
System.out.println("after grow = " + items);
}
}/*
ACTUAL OUTPUT:
getArea(5, 7) = 35
label("n=", 1,2,3) = n=3
before, number = 5
inside tryToChange, number = 99
after, number = 5
incremented() = 6
after array call, first = 99
sum(1, 2, 3) = 6
sum(5) = 5
sum() = 0
useFinal(5) = 10
after grow = [first, added]
THE SIX THINGS TO REMEMBER
1) A PARAMETER is declared in the signature. An ARGUMENT is supplied
at the call. The long names formal and actual mean the same thing.
2) JAVA IS ALWAYS PASS BY VALUE. For a primitive the value is copied
and changes are lost. For an object or array the reference is
copied, so changes to the CONTENTS are shared.
3) REASSIGNING a parameter is never visible to the caller, even for
an object. Only modifying what the reference points at is shared.
That is why so many methods return a result instead.
4) ARGUMENTS ARE MATCHED BY POSITION. Java has no named arguments,
so two same-type parameters can be swapped without complaint.
5) VARARGS, written Type... name, must be the LAST parameter, and
the compiler allocates an array on every call, so avoid it in
hot loops.
6) final stops REBINDING, not MODIFYING. A final reference still
points at a mutable object, and its contents can change freely.
*/
Common Java Technical Interview Questions & Answers
Interview Prep
Q1: What is the difference between a parameter and an argument?\nA1: A parameter is a variable declared in the method signature, such as width in getArea(int width, int height). An argument is the value supplied at the call site, such as the 5 in getArea(5, height). The longer terms formal parameter and actual argument describe the same two things.\nQ2: Does Java pass arguments by value or by reference?\nA2: Always by value, with no exceptions. What varies is what the value is: for a primitive it is the number itself, so changes are lost, while for an object it is the reference, so both sides still point at the same object and changes to its contents are shared.\nQ3: Why does changing a parameter not update the caller variable?\nA3: Because the method received a copy. Java is pass by value, so reassigning the parameter only changes the copy the method holds. The fix is either to return the new value or, for an object, to modify its contents rather than rebind the name.\nQ4: What is varargs in Java?\nA4: A parameter declared with three dots, such as int... values, that accepts any number of arguments including none. The compiler collects them into an array before the method body runs, so inside the method values is simply an int array. It must be the last parameter.\nQ5: Can a varargs parameter be followed by another parameter?\nA5: No. The varargs parameter must come last, because the compiler would otherwise have no way to know where the variable-length list ends. Putting another parameter after it is a compile error.\nQ6: Does a final parameter make an object immutable?\nA6: No. It prevents the reference being pointed at a different object, but the object it points at can still be modified. For a primitive parameter final and immutable are effectively the same thing, since there is no separate object to change.\nQ7: How many parameters should a method accept?\nA7: As few as possible. Past about three or four the risk of accidentally swapping two arguments of the same type rises sharply, and the compiler cannot help. Grouping related values into a small object or record removes that risk and makes the call site read better.\nQ8: Can an int be passed where a double is expected?\nA8: Yes, that direction is safe due to automatic widening, and the int is promoted. The reverse is a compile error because narrowing could lose the decimal part, so it requires an explicit cast and should only be used when the loss is genuinely intended.
Key Takeaways, Best Practices & Clean Code Rules
Java Best Practice & Production Rules
Return a value rather than mutating a parameter, since Java passes by value and a caller that expects a change to stick will not see one.
Share with friends, students, or your developer network
We value your privacy & transparency
OperateTools uses cookies and local storage to ensure basic tool functionality, preserve preferences, and analyze aggregated traffic. We never sell your personal data or index your document files. Learn more in our Privacy Policy.
Stay Updated
Enable Notifications?
Get real-time updates, instant tool alerts & daily news directly on your device.