Methods, Arrays, and Program Structure
Parameters, Arguments, and Return Values
আপনি একটি free preview lesson দেখছেন।
Lesson Overview
আগের lesson-এ আমরা basic methods শিখেছি।
Example:
static void greet() {
System.out.println("Welcome!");
}
কিন্তু এই method সবসময় একই কাজ করে।
Real programs-এ method সাধারণত input নেয় এবং result produce করে।
Example:
greet("Sakib");
greet("Subu");
greet("Sumu");
একই method different data নিয়ে কাজ করছে।
Methods আরও powerful হয় যখন আমরা বুঝি:
Parameters
Arguments
Return values
এই lesson-এ আমরা শিখব:
- What parameters are
- Parameters vs arguments
- Multiple parameters
- Parameter types
- Return values
return- Return types
- Using returned values
voidvs value-returning methods- Early return
- Designing useful method signatures
- Common beginner mistakes
Why Methods Need Input
Consider:
static void greet() {
System.out.println("Hello, Sakib!");
}
If we want to greet another person:
Hello, Subu!
we could create another method:
static void greetSubu() {
System.out.println("Hello, Subu!");
}
Then another:
static void greetSumu() {
System.out.println("Hello, Sumu!");
}
This clearly does not scale।
The behavior is the same।
Only the data changes।
What changes?
Name
So the method should receive the name as input।
Method Parameters
A parameter is a variable declared in the method signature that receives input when the method is called।
Example:
static void greet(
String name
) {
System.out.println(
"Hello, "
+ name
+ "!"
);
}
Now:
name
is a parameter।
Calling the Method
greet(
"Sakib"
);
greet(
"Subu"
);
greet(
"Sumu"
);
Output:
Hello, Sakib!
Hello, Subu!
Hello, Sumu!
One behavior can now work with different input।
Parameter vs Argument
These terms are related but not identical।
In the declaration:
static void greet(
String name
) {
}
name is a:
Parameter
In the call:
greet(
"Sakib"
);
"Sakib" is an:
Argument
A simple way to remember:
Parameter → variable in method declaration
Argument → actual value passed during method call
Another Example
Declaration:
static void printAge(
int age
) {
System.out.println(
age
);
}
Parameter:
age
Call:
printAge(
30
);
Argument:
30
Parameters Have Types
Java is statically typed।
Therefore every parameter has a type।
Example:
static void printCourse(
String courseName
) {
}
Here:
String
is the parameter type।
Another Example
static void showPrice(
long priceInPaisa
) {
System.out.println(
priceInPaisa
);
}
The method expects:
long
So this works:
showPrice(
499_000L
);
Passing the Wrong Type
Suppose:
static void printAge(
int age
) {
}
This is invalid:
printAge(
"thirty"
);
because the method expects:
int
but receives:
String
Java catches this at compile time।
Multiple Parameters
A method can receive multiple inputs।
Example:
static void printCourse(
String title,
long priceInPaisa
) {
System.out.println(
title
+ " - "
+ priceInPaisa
);
}
Call:
printCourse(
"Java and OOP Foundation",
499_000L
);
Parameter Order Matters
Consider:
static void printProfile(
String name,
int age
) {
}
Correct:
printProfile(
"Sakib",
30
);
Arguments correspond to parameters by position।
Conceptually:
"Sakib" → name
30 → age
Same Types Make Order More Important
Consider:
static void printFullName(
String firstName,
String lastName
) {
System.out.println(
firstName
+ " "
+ lastName
);
}
These calls both compile:
printFullName(
"Samiul",
"Sakib"
);
and:
printFullName(
"Sakib",
"Samiul"
);
Java cannot know which semantic order you intended because both arguments are String।
This is why:
Clear parameter names
Clear method names
Reasonable parameter order
matter।
Later, strong domain types can reduce this kind of ambiguity further।
Parameters Are Local Variables
Inside:
static void greet(
String name
) {
System.out.println(
name
);
}
name can be used inside the method।
But it cannot normally be accessed outside the method।
Example:
static void greet(
String name
) {
System.out.println(
name
);
}
This will not compile elsewhere:
System.out.println(
name
);
unless another variable named name exists in that scope।
Parameters Receive Values for Each Call
Consider:
static void greet(
String name
) {
System.out.println(
name
);
}
Call:
greet(
"Sakib"
);
greet(
"Jalisa"
);
During the first call:
name = "Sakib"
During the second call:
name = "Jalisa"
Each invocation gets its own parameter values।
Methods Can Receive Variables as Arguments
Arguments do not need to be literals।
Example:
String learnerName =
"Sakib";
greet(
learnerName
);
The current value of:
learnerName
is passed into the method।
Arguments Can Be Expressions
Suppose:
static void showTotal(
int total
) {
System.out.println(
total
);
}
You can call:
showTotal(
10 + 20
);
Java evaluates:
10 + 20
first।
Then passes:
30
to the method।
Another Expression Example
int price =
100;
int quantity =
3;
showTotal(
price * quantity
);
Argument becomes:
300
What Is a Return Value?
So far our methods perform actions:
static void greet(
String name
) {
System.out.println(
"Hello " + name
);
}
But sometimes a method should calculate something and give the result back।
Example:
static int add(
int first,
int second
) {
return first + second;
}
This method returns:
int
Calling a Returning Method
int result =
add(
10,
20
);
System.out.println(
result
);
Output:
30
Understanding the Signature
static int add(
int first,
int second
)
Breakdown:
static → method belongs to class
int → return type
add → method name
first → parameter
second → parameter
return
Inside:
return first + second;
two things happen:
- The expression is evaluated.
- The resulting value is sent back to the caller.
Return Type Must Match
Method:
static int getAge() {
return 30;
}
Valid because:
return type = int
returned value = int
Invalid Return Type
static int getAge() {
return "thirty";
}
This does not compile।
Why?
Method promises int
but returns String
Returning a String
static String createGreeting(
String name
) {
return "Hello, "
+ name
+ "!";
}
Usage:
String message =
createGreeting(
"Sakib"
);
System.out.println(
message
);
Output:
Hello, Sakib!
Returning a boolean
static boolean isAdult(
int age
) {
return age >= 18;
}
Usage:
boolean adult =
isAdult(
30
);
or directly:
if (
isAdult(
30
)
) {
System.out.println(
"Adult"
);
}
Return Values Can Be Used Directly
Instead of:
int result =
add(
5,
7
);
System.out.println(
result
);
you can write:
System.out.println(
add(
5,
7
)
);
Because the method call behaves like the value it returns।
Conceptually:
add(5, 7)
becomes:
12
Returned Values Can Become Arguments
Example:
static int doubleValue(
int value
) {
return value * 2;
}
static void printNumber(
int number
) {
System.out.println(
number
);
}
Then:
printNumber(
doubleValue(
10
)
);
Execution:
doubleValue(10)
↓
20
↓
printNumber(20)
Output:
20
Method Calls Can Be Composed
Example:
static int add(
int a,
int b
) {
return a + b;
}
static int multiply(
int a,
int b
) {
return a * b;
}
Then:
int result =
multiply(
add(
2,
3
),
4
);
Execution:
add(2, 3)
→ 5
multiply(5, 4)
→ 20
void vs Returning Methods
Compare:
static void printTotal(
int first,
int second
) {
System.out.println(
first + second
);
}
with:
static int calculateTotal(
int first,
int second
) {
return first + second;
}
The first:
Prints a result
The second:
Produces a result
The second is generally more reusable।
Why Returning Can Be Better Than Printing
Suppose:
static int calculateTotal(
int price,
int quantity
) {
return price * quantity;
}
Caller can decide what to do:
int total =
calculateTotal(
500,
3
);
Then:
System.out.println(
total
);
or:
if (
total > 1000
) {
System.out.println(
"Large order"
);
}
or pass it somewhere else।
The calculation method is not coupled to console output।
Separate Calculation from Presentation
Weak:
static void calculatePrice(
long price,
int quantity
) {
long total =
price * quantity;
System.out.println(
total
);
}
More flexible:
static long calculatePrice(
long price,
int quantity
) {
return price * quantity;
}
Then presentation decides:
long total =
calculatePrice(
499_000L,
2
);
System.out.println(
"Total: "
+ total
);
This principle becomes very important later when we separate:
Domain logic
Application logic
Presentation logic
return Ends Method Execution
When Java reaches a return statement, that method invocation ends immediately।
Example:
static int getNumber() {
return 10;
// unreachable
}
Code after an unconditional return cannot execute।
Java will reject unreachable statements in cases like this।
Early Return
return can also be used to leave a method early।
Example:
static void printAgeCategory(
int age
) {
if (age < 0) {
System.out.println(
"Invalid age"
);
return;
}
System.out.println(
"Age: "
+ age
);
}
Because this method is:
void
we can use:
return;
without a value।
Early Return with a Value
Example:
static String getAgeCategory(
int age
) {
if (age < 0) {
return "Invalid";
}
if (age < 18) {
return "Minor";
}
return "Adult";
}
Once a return runs, the remaining method statements are skipped।
Guard Clauses
Early returns are often used to reject special or invalid conditions first।
Example:
static boolean canEnroll(
boolean published,
boolean alreadyEnrolled
) {
if (!published) {
return false;
}
if (alreadyEnrolled) {
return false;
}
return true;
}
This can be easier to read than deeply nested conditions।
Later we will call this style:
Guard clauses
Every Execution Path Must Return a Value
Consider:
static String getResult(
boolean success
) {
if (success) {
return "Success";
}
}
This does not compile।
Why?
If:
success == false
the method reaches the end without returning a String।
Correct Version
static String getResult(
boolean success
) {
if (success) {
return "Success";
}
return "Failed";
}
Every possible execution path now returns a value।
Another Correct Version
static String getResult(
boolean success
) {
if (success) {
return "Success";
} else {
return "Failed";
}
}
Both are valid।
The first often needs less nesting।
Parameters Should Represent Needed Input
Suppose:
static long calculateTotal(
long price,
int quantity
) {
return price * quantity;
}
This method clearly states what it needs:
price
quantity
That's better than relying on unrelated global variables।
Avoid Hidden Input
Weak:
static long price =
500;
static int quantity =
4;
static long calculateTotal() {
return price * quantity;
}
The method signature does not reveal its dependencies।
Better for this simple calculation:
static long calculateTotal(
long price,
int quantity
) {
return price * quantity;
}
Now its required input is explicit।
Good Method Signatures Communicate Intent
Consider:
static boolean canEnroll(
boolean coursePublished,
boolean alreadyEnrolled
)
This is understandable।
But:
static boolean check(
boolean a,
boolean b
)
is not।
The signature is part of the method's API।
Too Many Parameters
A method can technically have many parameters:
static void createCourse(
String code,
String title,
String description,
long price,
String language,
String level,
int duration,
boolean published
) {
}
But many parameters may signal that the method is handling too much data or that some data belongs together conceptually।
Later we will learn how classes, records, and domain objects can model such groups more clearly।
For now:
Do not add parameters casually.
Give each parameter a clear purpose.
Boolean Parameters Can Be Ambiguous
Consider:
createCourse(
"JAVA",
"Java",
true
);
What does:
true
mean?
Published?
Visible?
Free?
Featured?
Boolean arguments can hide meaning at the call site।
We will revisit this in Professional Java Practices।
Method Names Should Match Return Meaning
Good:
static int calculateTotal(...)
Good:
static boolean isValid(...)
Good:
static String createGreeting(...)
Less clear:
static int doIt(...)
A caller should have a good idea what the returned value represents।
Command-Like vs Query-Like Methods
A useful early distinction:
A method that performs an action:
printReceipt();
sendMessage();
showMenu();
often returns:
void
A method that calculates or answers something:
calculateTotal();
isPublished();
findMaximum();
often returns a value।
This is not an absolute rule, but it is a useful design intuition।
Example: Calculate Course Price
public class Main {
public static void main(String[] args) {
long total =
calculateTotalPrice(
499_000L,
2
);
System.out.println(
"Total: "
+ total
);
}
static long calculateTotalPrice(
long priceInPaisa,
int quantity
) {
return priceInPaisa
* quantity;
}
}
Output:
Total: 998000
Example: Discount Calculation
static long applyDiscount(
long price,
int discountPercent
) {
long discount =
price
* discountPercent
/ 100;
return price - discount;
}
Usage:
long finalPrice =
applyDiscount(
5000,
10
);
Result:
4500
Example: Find Larger Number
static int max(
int first,
int second
) {
if (
first > second
) {
return first;
}
return second;
}
Usage:
int larger =
max(
10,
25
);
Result:
25
Example: Validate Course Title
static boolean isValidCourseTitle(
String title
) {
if (title == null) {
return false;
}
return !title.isBlank();
}
Usage:
if (
isValidCourseTitle(
"Java"
)
) {
System.out.println(
"Valid title"
);
}
Passing null
Reference-type parameters can receive:
null
unless the method prevents it।
Example:
static boolean isBlank(
String value
) {
return value == null
|| value.isBlank();
}
Then:
isBlank(
null
);
returns:
true
We'll later develop much stronger validation strategies।
Java Passes Arguments by Value
This is an important Java rule:
Java is always pass-by-value.
For primitives, the value itself is copied।
Example:
static void changeNumber(
int number
) {
number =
100;
}
Caller:
int value =
10;
changeNumber(
value
);
System.out.println(
value
);
Output:
10
Why?
number receives a copy of:
10
Changing the local parameter does not change value।
Primitive Pass-by-Value
Conceptually:
value = 10
call changeNumber(value)
copy:
number = 10
number becomes 100
value remains 10
What About Objects?
Objects often confuse beginners।
Java still passes by value।
But the copied value is an object reference।
We will study object references properly in the OOP module।
For now, remember:
Java does not use pass-by-reference.
Java always passes argument values.
Parameter Reassignment
Example:
static void rename(
String name
) {
name =
"New Name";
}
Caller:
String name =
"Sakib";
rename(
name
);
System.out.println(
name
);
Output:
Sakib
The parameter variable was reassigned locally।
The caller's variable was not reassigned।
String Is Also Immutable
There is another reason this example is straightforward:
String
objects are immutable।
Operations that appear to change a string actually create or reference another string value।
We'll explore immutability much more later।
Method Parameters and Validation
Methods should sometimes validate their inputs।
Example:
static long calculateTotal(
long price,
int quantity
) {
if (price < 0) {
throw new IllegalArgumentException(
"Price cannot be negative."
);
}
if (quantity < 0) {
throw new IllegalArgumentException(
"Quantity cannot be negative."
);
}
return price * quantity;
}
We haven't studied exceptions deeply yet, so focus on the principle:
A method should define what input is acceptable.
Don't Validate the Same Thing Everywhere
Later we will build strong types such as:
CourseCode
LearnerId
Once those types guarantee their own validity, downstream methods should not repeatedly validate their internal values।
This is one reason good type design matters।
A Practical Example
Let's build a simple course-price program।
public class Main {
public static void main(String[] args) {
String course =
formatCourseName(
"java and oop foundation"
);
long total =
calculateTotal(
499_000L,
2
);
boolean expensive =
isExpensive(
total
);
System.out.println(
course
);
System.out.println(
total
);
System.out.println(
expensive
);
}
static String formatCourseName(
String name
) {
return name.toUpperCase();
}
static long calculateTotal(
long price,
int quantity
) {
return price * quantity;
}
static boolean isExpensive(
long amount
) {
return amount > 500_000L;
}
}
Each method performs a clear task।
Avoid Mixing Too Many Responsibilities
Weak:
static long calculateTotal(
long price,
int quantity
) {
long total =
price * quantity;
System.out.println(
"Calculating..."
);
System.out.println(
total
);
return total;
}
This method both:
Calculates
Prints presentation output
A cleaner version:
static long calculateTotal(
long price,
int quantity
) {
return price * quantity;
}
Then caller decides how to display it।
Reusing a Returning Method
Because the method returns data:
static long calculateTotal(
long price,
int quantity
)
we can use it in:
Console output
Conditions
Other calculations
Another method call
Later object construction
Returning useful values generally makes pure calculations more reusable।
Common Beginner Mistake 1: Forgetting Arguments
Declaration:
static void greet(
String name
) {
}
Invalid call:
greet();
Java expects one String argument।
Common Beginner Mistake 2: Too Many Arguments
Declaration:
static void greet(
String name
) {
}
Invalid:
greet(
"Sakib",
"Subu"
);
The argument count does not match।
Common Beginner Mistake 3: Wrong Argument Order
static void createProfile(
String name,
int age
) {
}
Invalid:
createProfile(
30,
"Sakib"
);
because parameter types do not match the positions।
Common Beginner Mistake 4: Returning Nothing from Non-void
Invalid:
static int calculate() {
System.out.println(
"Calculating"
);
}
The method promises:
int
but does not return an int।
Common Beginner Mistake 5: Returning a Value from void
Invalid:
static void calculate() {
return 10;
}
A void method cannot return a value।
It may only use:
return;
to exit early।
Common Beginner Mistake 6: Wrong Return Type
static boolean isAdult(
int age
) {
return "yes";
}
Invalid because:
String != boolean
Common Beginner Mistake 7: Ignoring a Useful Return Value
This is legal:
calculateTotal(
100,
5
);
but if the method only returns a value and has no side effects, the result is immediately discarded।
Usually you intended:
long total =
calculateTotal(
100,
5
);
Practice 1: Greeting Parameter
Create:
static void greet(
String name
)
that prints:
Hello, <name>!
Call it for three names।
Solution
public class Main {
public static void main(String[] args) {
greet(
"Sakib"
);
greet(
"Subu"
);
greet(
"Sumu"
);
}
static void greet(
String name
) {
System.out.println(
"Hello, "
+ name
+ "!"
);
}
}
Practice 2: Add Two Numbers
Create:
static int add(
int first,
int second
)
that returns their sum।
Solution
static int add(
int first,
int second
) {
return first + second;
}
Usage:
int result =
add(
10,
20
);
Practice 3: Calculate Rectangle Area
Create:
static int calculateArea(
int width,
int height
)
Expected:
calculateArea(
5,
4
)
returns:
20
Solution
static int calculateArea(
int width,
int height
) {
return width * height;
}
Practice 4: Adult Check
Write:
static boolean isAdult(
int age
)
Solution
static boolean isAdult(
int age
) {
return age >= 18;
}
Practice 5: Largest Number
Write:
static int max(
int first,
int second
)
without using Math.max()।
Solution
static int max(
int first,
int second
) {
if (
first > second
) {
return first;
}
return second;
}
Practice 6: Course Availability
Create:
static boolean isAvailable(
boolean published,
boolean archived
)
A course is available when:
published == true
archived == false
Solution
static boolean isAvailable(
boolean published,
boolean archived
) {
return published
&& !archived;
}
Later we'll replace multiple booleans like this with stronger enum-based lifecycle models।
Practice 7: Early Return
Create a method:
static String classifyScore(
int score
)
Rules:
Below 0 or above 100 → Invalid
90+ → Excellent
70+ → Good
Otherwise → Needs Improvement
Solution
static String classifyScore(
int score
) {
if (
score < 0
|| score > 100
) {
return "Invalid";
}
if (score >= 90) {
return "Excellent";
}
if (score >= 70) {
return "Good";
}
return "Needs Improvement";
}
Predict the Output
public class Main {
public static void main(String[] args) {
int value =
multiply(
add(
2,
3
),
4
);
System.out.println(
value
);
}
static int add(
int a,
int b
) {
return a + b;
}
static int multiply(
int a,
int b
) {
return a * b;
}
}
Answer
20
Because:
add(2, 3)
→ 5
multiply(5, 4)
→ 20
True or False
- A parameter is declared in a method signature.
- An argument is the actual value passed during a call.
- Parameter order does not matter.
- Java checks parameter types.
- A
voidmethod returns no result value. returncan send a value to the caller.- A method returning
intmay return aString. - Every execution path of a value-returning method must provide a compatible result.
- Returned values can be passed into other methods.
- Java is pass-by-reference.
Answers
1. True
2. True
3. False
4. True
5. True
6. True
7. False
8. True
9. True
10. False
Knowledge Check
Question 1
What is a parameter?
Question 2
What is an argument?
Question 3
Why do parameters make methods more reusable?
Question 4
What does a return type describe?
Question 5
What does return do?
Question 6
What is the difference between void and int in a method declaration?
Question 7
Can a returned value be used directly as another method's argument?
Question 8
Why is returning a calculation usually more reusable than printing it directly?
Question 9
What happens when execution reaches return?
Question 10
Is Java pass-by-reference?
Knowledge Check Answers
Answer 1
A parameter is a typed local variable declared in the method signature that receives input for a method invocation।
Answer 2
An argument is the actual value or expression supplied when calling the method।
Answer 3
The same behavior can operate on different input instead of hard-coding one specific value।
Answer 4
It describes the type of value the method promises to provide to its caller।
Answer 5
It ends the current method invocation and, for a value-returning method, sends a result back to the caller।
Answer 6
void means no result value is returned, while int means the method must return an integer-compatible value।
Answer 7
Yes।
Example:
printNumber(
calculateTotal(
10,
2
)
);
Answer 8
The caller can decide whether to print, compare, store, transform, or pass the result elsewhere।
Answer 9
The current method invocation ends immediately and execution returns to its caller।
Answer 10
No।
Java is always pass-by-value।
For object arguments, the copied value is a reference to the object।
Lesson Summary
এই lesson-এ আমরা methods-এর input এবং output model শিখেছি।
We learned:
- Parameters method declaration-এর অংশ
- Arguments method call-এর actual values
- Parameters have Java types
- Argument count, order, and types must match
- Methods may receive multiple parameters
- Parameters are local to each invocation
- Methods can return values
- Return type defines what kind of result is produced
returnsends the result back and ends executionvoidmeans no result value- Returning calculations often creates more reusable code than printing directly
- Returned values can be stored, compared, printed, or passed into other methods
- Early return can simplify control flow
- Every normal execution path of a non-
voidmethod must return a compatible value - Java is always pass-by-value
- Good method signatures make required input and produced output clear
A useful way to think about a method is:
Input
↓
Method behavior
↓
Output
For example:
price + quantity
↓
calculateTotal(...)
↓
total
This input/output model will become fundamental when we start building larger programs and objects।
Next Lesson
পরবর্তী lesson:
Scope, Static Methods, and Method Overloading
আমরা শিখব:
- Local variables
- Block scope
- Method scope
- Variable shadowing
- Why scope matters
staticmethods- Instance methods preview
- Method overloading
- Overload resolution
- Common overloading mistakes