Introduction
Imagine you're at a coffee shop—when you order, you tell the barista what you want (arguments), and they have a recipe (method parameters) to make your drink. In Java, methods are like these recipes, and parameters are the ingredients they expect, while arguments are the actual ingredients you provide!
Parameters and arguments are fundamental to method communication in Java, allowing you to pass data into methods, making them flexible and reusable.
What are Parameters and Arguments?
- Parameters: Variables in a method declaration—the "ingredients list"
- Arguments: Actual values passed to the method when it's called—the "actual ingredients"
Key Characteristics:
- 🎯 Parameters define, arguments provide
- 🔄 Data flow: Arguments → Parameters
- 📝 Type safety: Arguments must match parameter types
- 🏗️ Flexibility: Methods can work with different data
Code Explanation with Examples
Example 1: Basic Parameters and Arguments
public class BasicParameters {
public static void main(String[] args) {
System.out.println("=== BASIC PARAMETERS AND ARGUMENTS ===");
// Method with parameters - definition
greetPerson("Alice", 25); // "Alice" and 25 are arguments
greetPerson("Bob", 30); // Different arguments
greetPerson("Charlie", 22); // Same method, different data
// Multiple parameters of different types
displayStudentInfo("John Doe", 85.5, true);
// No parameters
sayHello();
// Using return values
int result = addNumbers(10, 20);
System.out.println("Sum: " + result);
// Using the result in another calculation
int finalResult = multiplyNumbers(result, 3);
System.out.println("Final result: " + finalResult);
}
// Method with parameters (name and age are parameters)
public static void greetPerson(String name, int age) {
System.out.println("Hello " + name + ", you are " + age + " years old!");
}
// Multiple parameters of different types
public static void displayStudentInfo(String name, double grade, boolean isPassing) {
System.out.println("\nStudent: " + name);
System.out.println("Grade: " + grade);
System.out.println("Passing: " + (isPassing ? "Yes" : "No"));
}
// Method with no parameters
public static void sayHello() {
System.out.println("\nHello from a parameter-less method!");
}
// Method with parameters and return value
public static int addNumbers(int num1, int num2) {
return num1 + num2;
}
// Method using previous result
public static int multiplyNumbers(int a, int b) {
return a * b;
}
}
Output:
=== BASIC PARAMETERS AND ARGUMENTS === Hello Alice, you are 25 years old! Hello Bob, you are 30 years old! Hello Charlie, you are 22 years old! Student: John Doe Grade: 85.5 Passing: Yes Hello from a parameter-less method! Sum: 30 Final result: 90
Example 2: Parameter Types and Passing Mechanisms
public class ParameterTypes {
public static void main(String[] args) {
System.out.println("=== PARAMETER TYPES AND PASSING MECHANISMS ===");
// Primitive types (pass by value)
int x = 10;
int y = 20;
System.out.println("Before swap - x: " + x + ", y: " + y);
swapPrimitives(x, y); // Copies of x and y are passed
System.out.println("After swap - x: " + x + ", y: " + y);
// Reference types (pass by value of reference)
int[] numbers = {1, 2, 3};
System.out.println("\nBefore modification: " + java.util.Arrays.toString(numbers));
modifyArray(numbers); // Reference copy is passed
System.out.println("After modification: " + java.util.Arrays.toString(numbers));
// String (immutable, behaves like primitive)
String name = "Alice";
System.out.println("\nBefore modification: " + name);
modifyString(name); // String is immutable, original unchanged
System.out.println("After modification: " + name);
// Object parameters
Person person = new Person("John", 25);
System.out.println("\nBefore modification: " + person);
modifyObject(person); // Object can be modified through reference
System.out.println("After modification: " + person);
// Demonstrating pass-by-value with objects
System.out.println("\n=== REASSIGNMENT DEMONSTRATION ===");
Person original = new Person("Original", 30);
System.out.println("Before reassignment: " + original);
reassignObject(original);
System.out.println("After reassignment: " + original); // Original unchanged
}
// Primitive parameters - pass by value (copies)
public static void swapPrimitives(int a, int b) {
int temp = a;
a = b;
b = temp;
System.out.println("Inside swap - a: " + a + ", b: " + b);
}
// Array parameter - reference is copied, but points to same array
public static void modifyArray(int[] arr) {
if (arr.length > 0) {
arr[0] = 100; // Modifies the original array
}
System.out.println("Inside method: " + java.util.Arrays.toString(arr));
}
// String parameter - immutable, behaves like primitive
public static void modifyString(String str) {
str = str.toUpperCase(); // Creates new String, doesn't affect original
System.out.println("Inside method: " + str);
}
// Object parameter - reference copy, can modify object
public static void modifyObject(Person p) {
p.setAge(p.getAge() + 1); // Modifies the original object
p.setName(p.getName() + " Modified");
System.out.println("Inside method: " + p);
}
// Demonstrating that reference is passed by value
public static void reassignObject(Person p) {
p = new Person("New Person", 99); // Only affects local copy
System.out.println("Inside reassignment: " + p);
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getters and setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
Output:
=== PARAMETER TYPES AND PASSING MECHANISMS ===
Before swap - x: 10, y: 20
Inside swap - a: 20, b: 10
After swap - x: 10, y: 20
Before modification: [1, 2, 3]
Inside method: [100, 2, 3]
After modification: [100, 2, 3]
Before modification: Alice
Inside method: ALICE
After modification: Alice
Before modification: Person{name='John', age=25}
Inside method: Person{name='John Modified', age=26}
After modification: Person{name='John Modified', age=26}
=== REASSIGNMENT DEMONSTRATION ===
Before reassignment: Person{name='Original', age=30}
Inside reassignment: Person{name='New Person', age=99}
After reassignment: Person{name='Original', age=30}
Example 3: Method Overloading with Different Parameters
public class MethodOverloading {
public static void main(String[] args) {
System.out.println("=== METHOD OVERLOADING WITH PARAMETERS ===");
// Same method name, different parameter types
display(10); // int version
display(3.14); // double version
display("Hello"); // String version
display(5, 3.14); // int, double version
display(3.14, 5); // double, int version
// Calculator with overloaded methods
System.out.println("\n=== CALCULATOR DEMONSTRATION ===");
System.out.println("Add ints: " + add(5, 10));
System.out.println("Add doubles: " + add(5.5, 10.5));
System.out.println("Add three ints: " + add(5, 10, 15));
System.out.println("Add Strings: " + add("Hello", " World"));
// Area calculations with different parameters
System.out.println("\n=== AREA CALCULATIONS ===");
System.out.println("Area of circle (radius 5): " + calculateArea(5.0));
System.out.println("Area of rectangle (4x6): " + calculateArea(4, 6));
System.out.println("Area of triangle (base 3, height 4): " + calculateArea(3.0, 4.0));
System.out.println("Area of square (side 5): " + calculateArea(5));
// Constructor overloading
System.out.println("\n=== CONSTRUCTOR OVERLOADING ===");
Student student1 = new Student("Alice");
Student student2 = new Student("Bob", 20);
Student student3 = new Student("Charlie", 22, "Computer Science");
student1.displayInfo();
student2.displayInfo();
student3.displayInfo();
}
// Overloaded display methods
public static void display(int number) {
System.out.println("Integer: " + number);
}
public static void display(double number) {
System.out.println("Double: " + number);
}
public static void display(String text) {
System.out.println("String: " + text);
}
public static void display(int a, double b) {
System.out.println("int, double: " + a + ", " + b);
}
public static void display(double a, int b) {
System.out.println("double, int: " + a + ", " + b);
}
// Overloaded add methods
public static int add(int a, int b) {
return a + b;
}
public static double add(double a, double b) {
return a + b;
}
public static int add(int a, int b, int c) {
return a + b + c;
}
public static String add(String a, String b) {
return a + b;
}
// Overloaded area calculation methods
public static double calculateArea(double radius) {
return Math.PI * radius * radius; // Circle area
}
public static int calculateArea(int length, int width) {
return length * width; // Rectangle area
}
public static double calculateArea(double base, double height) {
return 0.5 * base * height; // Triangle area
}
public static int calculateArea(int side) {
return side * side; // Square area
}
}
class Student {
private String name;
private int age;
private String major;
// Constructor overloading
public Student(String name) {
this.name = name;
this.age = 18; // Default age
this.major = "Undeclared";
}
public Student(String name, int age) {
this.name = name;
this.age = age;
this.major = "Undeclared";
}
public Student(String name, int age, String major) {
this.name = name;
this.age = age;
this.major = major;
}
public void displayInfo() {
System.out.println("Student: " + name + ", Age: " + age + ", Major: " + major);
}
}
Output:
=== METHOD OVERLOADING WITH PARAMETERS === Integer: 10 Double: 3.14 String: Hello int, double: 5, 3.14 double, int: 3.14, 5 === CALCULATOR DEMONSTRATION === Add ints: 15 Add doubles: 16.0 Add three ints: 30 Add Strings: Hello World === AREA CALCULATIONS === Area of circle (radius 5): 78.53981633974483 Area of rectangle (4x6): 24 Area of triangle (base 3, height 4): 6.0 Area of square (side 5): 25 === CONSTRUCTOR OVERLOADING === Student: Alice, Age: 18, Major: Undeclared Student: Bob, Age: 20, Major: Undeclared Student: Charlie, Age: 22, Major: Computer Science
Example 4: Variable Arguments (Varargs)
public class VariableArguments {
public static void main(String[] args) {
System.out.println("=== VARIABLE ARGUMENTS (VARARGS) ===");
// Calling methods with different numbers of arguments
printNumbers(); // No arguments
printNumbers(1); // One argument
printNumbers(1, 2, 3); // Three arguments
printNumbers(1, 2, 3, 4, 5, 6); // Six arguments
// Mixed parameters with varargs
System.out.println("\n=== MIXED PARAMETERS ===");
printInfo("Grades:", 85, 92, 78, 96, 88);
printInfo("Scores:", 100, 95);
printInfo("Empty:");
// Varargs with different types
System.out.println("\n=== MULTIPLE VARARGS ===");
processData("Data points:", 10, 20.5, "Hello", true);
// Real-world examples
System.out.println("\n=== REAL-WORLD EXAMPLES ===");
// Shopping cart total
double total = calculateTotal(19.99, 5.99, 12.49, 8.75);
System.out.printf("Shopping cart total: $%.2f%n", total);
// Student average grade
double average = calculateAverage(85, 92, 78, 96, 88);
System.out.printf("Student average: %.1f%%%n", average);
// Find maximum value
int max = findMaximum(15, 8, 23, 17, 9, 31, 12);
System.out.println("Maximum value: " + max);
// String concatenation
String fullName = concatenateNames("John", "Michael", "Doe");
System.out.println("Full name: " + fullName);
}
// Varargs method - can take 0 or more integers
public static void printNumbers(int... numbers) {
System.out.print("Numbers (" + numbers.length + "): ");
for (int num : numbers) {
System.out.print(num + " ");
}
System.out.println();
}
// Mixed parameters - regular parameter + varargs
public static void printInfo(String message, int... values) {
System.out.print(message + " ");
for (int value : values) {
System.out.print(value + " ");
}
System.out.println();
}
// Varargs with Object type - accepts any type
public static void processData(String label, Object... items) {
System.out.print(label + " ");
for (Object item : items) {
System.out.print(item + " (" + item.getClass().getSimpleName() + ") ");
}
System.out.println();
}
// Calculate total of variable number of prices
public static double calculateTotal(double... prices) {
double total = 0.0;
for (double price : prices) {
total += price;
}
return total;
}
// Calculate average of variable number of grades
public static double calculateAverage(int... grades) {
if (grades.length == 0) return 0.0;
int sum = 0;
for (int grade : grades) {
sum += grade;
}
return (double) sum / grades.length;
}
// Find maximum value from variable arguments
public static int findMaximum(int... numbers) {
if (numbers.length == 0) return Integer.MIN_VALUE;
int max = numbers[0];
for (int num : numbers) {
if (num > max) {
max = num;
}
}
return max;
}
// Concatenate variable number of name parts
public static String concatenateNames(String... nameParts) {
StringBuilder fullName = new StringBuilder();
for (String part : nameParts) {
if (fullName.length() > 0) {
fullName.append(" ");
}
fullName.append(part);
}
return fullName.toString();
}
// ❌ Invalid - multiple varargs not allowed
// public static void invalidMethod(String... strings, int... numbers) {}
// ✅ Valid - only one varargs parameter, must be last
public static void validMethod(String regularParam, int... varargsParam) {
System.out.println("Regular: " + regularParam + ", Varargs length: " + varargsParam.length);
}
}
Output:
=== VARIABLE ARGUMENTS (VARARGS) === Numbers (0): Numbers (1): 1 Numbers (3): 1 2 3 Numbers (6): 1 2 3 4 5 6 === MIXED PARAMETERS === Grades: 85 92 78 96 88 Scores: 100 95 Empty: === MULTIPLE VARARGS === Data points: 10 (Integer) 20.5 (Double) Hello (String) true (Boolean) === REAL-WORLD EXAMPLES === Shopping cart total: $47.22 Student average: 87.8% Maximum value: 31 Full name: John Michael Doe
Example 5: Parameter Validation and Best Practices
public class ParameterValidation {
public static void main(String[] args) {
System.out.println("=== PARAMETER VALIDATION AND BEST PRACTICES ===");
// Testing with valid parameters
System.out.println("=== VALID PARAMETERS ===");
try {
BankAccount account = new BankAccount("Alice", 1000.0);
System.out.println("Account created: " + account);
account.deposit(500.0);
System.out.println("After deposit: " + account);
account.withdraw(200.0);
System.out.println("After withdrawal: " + account);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
// Testing with invalid parameters
System.out.println("\n=== INVALID PARAMETERS ===");
try {
BankAccount invalidAccount = new BankAccount("", -100.0); // Empty name, negative balance
} catch (IllegalArgumentException e) {
System.out.println("Expected error: " + e.getMessage());
}
try {
BankAccount account = new BankAccount("Bob", 500.0);
account.deposit(-50.0); // Negative deposit
} catch (IllegalArgumentException e) {
System.out.println("Expected error: " + e.getMessage());
}
try {
BankAccount account = new BankAccount("Charlie", 100.0);
account.withdraw(200.0); // Insufficient funds
} catch (IllegalArgumentException e) {
System.out.println("Expected error: " + e.getMessage());
}
// Using utility methods with validation
System.out.println("\n=== UTILITY METHODS WITH VALIDATION ===");
System.out.println("Factorial of 5: " + MathUtils.factorial(5));
System.out.println("GCD of 48 and 18: " + MathUtils.gcd(48, 18));
try {
System.out.println("Factorial of -1: " + MathUtils.factorial(-1));
} catch (IllegalArgumentException e) {
System.out.println("Error calculating factorial: " + e.getMessage());
}
// Demonstrating defensive copying
System.out.println("\n=== DEFENSIVE COPYING ===");
defensiveCopyingDemo();
}
public static void defensiveCopyingDemo() {
int[] scores = {85, 92, 78};
GradeTracker tracker = new GradeTracker(scores);
System.out.println("Original scores: " + java.util.Arrays.toString(scores));
System.out.println("Tracker grades: " + tracker);
// Modify original array - should not affect tracker
scores[0] = 100;
System.out.println("After modifying original: " + java.util.Arrays.toString(scores));
System.out.println("Tracker grades (unchanged): " + tracker);
// Get grades from tracker - returns copy
int[] trackerGrades = tracker.getGrades();
trackerGrades[0] = 50; // Should not affect tracker's internal array
System.out.println("After modifying returned array: " + java.util.Arrays.toString(trackerGrades));
System.out.println("Tracker grades (unchanged): " + tracker);
}
}
class BankAccount {
private String ownerName;
private double balance;
// Constructor with parameter validation
public BankAccount(String ownerName, double initialBalance) {
validateName(ownerName);
validateAmount(initialBalance, "Initial balance");
this.ownerName = ownerName;
this.balance = initialBalance;
}
// Method with parameter validation
public void deposit(double amount) {
validateAmount(amount, "Deposit amount");
balance += amount;
}
public void withdraw(double amount) {
validateAmount(amount, "Withdrawal amount");
if (amount > balance) {
throw new IllegalArgumentException("Insufficient funds. Balance: " + balance + ", Requested: " + amount);
}
balance -= amount;
}
// Validation methods
private void validateName(String name) {
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("Owner name cannot be null or empty");
}
}
private void validateAmount(double amount, String amountType) {
if (amount < 0) {
throw new IllegalArgumentException(amountType + " cannot be negative: " + amount);
}
}
@Override
public String toString() {
return String.format("BankAccount{owner='%s', balance=$%.2f}", ownerName, balance);
}
}
class MathUtils {
// Method with preconditions
public static int factorial(int n) {
// Validate parameter
if (n < 0) {
throw new IllegalArgumentException("Factorial is not defined for negative numbers: " + n);
}
if (n > 20) { // 21! exceeds int range
throw new IllegalArgumentException("Factorial too large for int: " + n);
}
int result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}
// Method with parameter validation and meaningful names
public static int gcd(int a, int b) {
// Handle edge cases
if (a == 0 && b == 0) {
throw new IllegalArgumentException("GCD is undefined for (0, 0)");
}
// Ensure positive values for algorithm
a = Math.abs(a);
b = Math.abs(b);
// Euclidean algorithm
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
}
class GradeTracker {
private int[] grades;
// Constructor with defensive copy
public GradeTracker(int[] grades) {
if (grades == null) {
throw new IllegalArgumentException("Grades array cannot be null");
}
// Defensive copy - create new array
this.grades = new int[grades.length];
System.arraycopy(grades, 0, this.grades, 0, grades.length);
}
// Getter with defensive copy
public int[] getGrades() {
int[] copy = new int[grades.length];
System.arraycopy(grades, 0, copy, 0, grades.length);
return copy;
}
public void addGrade(int grade) {
// Validate grade
if (grade < 0 || grade > 100) {
throw new IllegalArgumentException("Grade must be between 0 and 100: " + grade);
}
// Resize array and add new grade
int[] newGrades = new int[grades.length + 1];
System.arraycopy(grades, 0, newGrades, 0, grades.length);
newGrades[grades.length] = grade;
grades = newGrades;
}
public double calculateAverage() {
if (grades.length == 0) return 0.0;
int sum = 0;
for (int grade : grades) {
sum += grade;
}
return (double) sum / grades.length;
}
@Override
public String toString() {
return "GradeTracker{grades=" + java.util.Arrays.toString(grades) +
", average=" + String.format("%.1f", calculateAverage()) + "}";
}
}
Output:
=== PARAMETER VALIDATION AND BEST PRACTICES ===
=== VALID PARAMETERS ===
Account created: BankAccount{owner='Alice', balance=$1000.00}
After deposit: BankAccount{owner='Alice', balance=$1500.00}
After withdrawal: BankAccount{owner='Alice', balance=$1300.00}
=== INVALID PARAMETERS ===
Expected error: Owner name cannot be null or empty
Expected error: Deposit amount cannot be negative: -50.0
Expected error: Insufficient funds. Balance: 100.0, Requested: 200.0
=== UTILITY METHODS WITH VALIDATION ===
Factorial of 5: 120
GCD of 48 and 18: 6
Error calculating factorial: Factorial is not defined for negative numbers: -1
=== DEFENSIVE COPYING ===
Original scores: [85, 92, 78]
Tracker grades: GradeTracker{grades=[85, 92, 78], average=85.0}
After modifying original: [100, 92, 78]
Tracker grades (unchanged): GradeTracker{grades=[85, 92, 78], average=85.0}
After modifying returned array: [50, 92, 78]
Tracker grades (unchanged): GradeTracker{grades=[85, 92, 78], average=85.0}
Example 6: Advanced Parameter Techniques
import java.util.Arrays;
public class AdvancedParameterTechniques {
public static void main(String[] args) {
System.out.println("=== ADVANCED PARAMETER TECHNIQUES ===");
// Method references as parameters
System.out.println("=== METHOD REFERENCES ===");
processNumbers(5, 3, AdvancedParameterTechniques::add);
processNumbers(5, 3, AdvancedParameterTechniques::multiply);
processNumbers(8, 2, AdvancedParameterTechniques::divide);
// Lambda expressions as parameters
System.out.println("\n=== LAMBDA EXPRESSIONS ===");
processNumbers(10, 4, (a, b) -> a - b); // Subtraction
processNumbers(2, 5, (a, b) -> (int) Math.pow(a, b)); // Power
processNumbers(7, 3, (a, b) -> a % b); // Modulo
// Generic methods with type parameters
System.out.println("\n=== GENERIC METHODS ===");
System.out.println("Max of 5 and 10: " + findMax(5, 10));
System.out.println("Max of 3.14 and 2.71: " + findMax(3.14, 2.71));
System.out.println("Max of 'apple' and 'banana': " + findMax("apple", "banana"));
// Array of generic types
Integer[] intArray = {1, 5, 3, 9, 2};
String[] strArray = {"dog", "cat", "elephant", "bird"};
System.out.println("Max in int array: " + findMaxInArray(intArray));
System.out.println("Max in str array: " + findMaxInArray(strArray));
// Optional parameters simulation
System.out.println("\n=== OPTIONAL PARAMETERS SIMULATION ===");
connectToDatabase(); // All defaults
connectToDatabase("192.168.1.100"); // Custom host, other defaults
connectToDatabase("192.168.1.100", 3307); // Custom host and port
connectToDatabase("192.168.1.100", 3307, "mydb"); // All custom
// Builder pattern for complex parameters
System.out.println("\n=== BUILDER PATTERN ===");
EmailMessage message = new EmailMessage.Builder()
.setTo("[email protected]")
.setSubject("Hello World")
.setBody("This is a test email")
.setCc("[email protected]")
.setBcc("[email protected]")
.setPriority(EmailMessage.Priority.HIGH)
.build();
message.send();
}
// Functional interface for operations
@FunctionalInterface
interface MathOperation {
int operate(int a, int b);
}
// Method that accepts another method as parameter
public static void processNumbers(int a, int b, MathOperation operation) {
int result = operation.operate(a, b);
System.out.println(a + " op " + b + " = " + result);
}
// Concrete operations
public static int add(int a, int b) {
return a + b;
}
public static int multiply(int a, int b) {
return a * b;
}
public static int divide(int a, int b) {
if (b == 0) throw new IllegalArgumentException("Division by zero");
return a / b;
}
// Generic method with type parameter
public static <T extends Comparable<T>> T findMax(T a, T b) {
return a.compareTo(b) >= 0 ? a : b;
}
// Generic method with array parameter
public static <T extends Comparable<T>> T findMaxInArray(T[] array) {
if (array == null || array.length == 0) {
throw new IllegalArgumentException("Array cannot be null or empty");
}
T max = array[0];
for (T element : array) {
if (element.compareTo(max) > 0) {
max = element;
}
}
return max;
}
// Simulating optional parameters with method overloading
public static void connectToDatabase() {
connectToDatabase("localhost", 3306, "testdb");
}
public static void connectToDatabase(String host) {
connectToDatabase(host, 3306, "testdb");
}
public static void connectToDatabase(String host, int port) {
connectToDatabase(host, port, "testdb");
}
public static void connectToDatabase(String host, int port, String database) {
System.out.printf("Connecting to database: %s:%d/%s%n", host, port, database);
}
}
// Builder pattern for complex parameter objects
class EmailMessage {
public enum Priority { LOW, NORMAL, HIGH }
private final String to;
private final String subject;
private final String body;
private final String cc;
private final String bcc;
private final Priority priority;
// Private constructor - use Builder
private EmailMessage(Builder builder) {
this.to = builder.to;
this.subject = builder.subject;
this.body = builder.body;
this.cc = builder.cc;
this.bcc = builder.bcc;
this.priority = builder.priority;
}
// Builder class
public static class Builder {
// Required parameters
private String to;
private String subject;
private String body;
// Optional parameters with defaults
private String cc = "";
private String bcc = "";
private Priority priority = Priority.NORMAL;
public Builder setTo(String to) {
this.to = to;
return this;
}
public Builder setSubject(String subject) {
this.subject = subject;
return this;
}
public Builder setBody(String body) {
this.body = body;
return this;
}
public Builder setCc(String cc) {
this.cc = cc;
return this;
}
public Builder setBcc(String bcc) {
this.bcc = bcc;
return this;
}
public Builder setPriority(Priority priority) {
this.priority = priority;
return this;
}
public EmailMessage build() {
// Validate required parameters
if (to == null || to.trim().isEmpty()) {
throw new IllegalStateException("Recipient (to) is required");
}
if (subject == null || subject.trim().isEmpty()) {
throw new IllegalStateException("Subject is required");
}
if (body == null || body.trim().isEmpty()) {
throw new IllegalStateException("Body is required");
}
return new EmailMessage(this);
}
}
public void send() {
System.out.println("Sending email:");
System.out.println(" To: " + to);
System.out.println(" Subject: " + subject);
System.out.println(" Body: " + body);
if (!cc.isEmpty()) System.out.println(" CC: " + cc);
if (!bcc.isEmpty()) System.out.println(" BCC: " + bcc);
System.out.println(" Priority: " + priority);
System.out.println("Email sent successfully!");
}
}
Output:
=== ADVANCED PARAMETER TECHNIQUES === === METHOD REFERENCES === 5 op 3 = 8 5 op 3 = 15 8 op 2 = 4 === LAMBDA EXPRESSIONS === 10 op 4 = 6 2 op 5 = 32 7 op 3 = 1 === GENERIC METHODS === Max of 5 and 10: 10 Max of 3.14 and 2.71: 3.14 Max of 'apple' and 'banana': banana Max in int array: 9 Max in str array: elephant === OPTIONAL PARAMETERS SIMULATION === Connecting to database: localhost:3306/testdb Connecting to database: 192.168.1.100:3306/testdb Connecting to database: 192.168.1.100:3307/testdb Connecting to database: 192.168.1.100:3307/mydb === BUILDER PATTERN === Sending email: To: [email protected] Subject: Hello World Body: This is a test email CC: [email protected] BCC: [email protected] Priority: HIGH Email sent successfully!
Parameter Passing Mechanisms
| Type | Mechanism | Effect on Original | Example |
|---|---|---|---|
| Primitives | Pass by value | No change | int, double, boolean |
| Objects | Pass by reference value | Can modify object | StringBuilder, arrays |
| Immutable Objects | Pass by reference value | No change (new objects) | String, Integer |
Parameter Types Summary
| Type | Syntax | Use Case |
|---|---|---|
| Primitive | int num | Simple values |
| Reference | String str | Objects, arrays |
| Varargs | int... numbers | Variable arguments |
| Functional | MathOperation op | Lambdas, method references |
| Generic | <T> T method(T param) | Type-safe reusable code |
Best Practices
✅ Do:
- Use descriptive parameter names:
calculateArea(double radius) - Validate parameters: Check for null, empty, invalid ranges
- Use final for parameters that shouldn't be modified
- Prefer immutability: Use immutable objects as parameters
- Use varargs for methods that accept variable arguments
- Document parameters with JavaDoc
- Use builder pattern for complex parameter sets
❌ Don't:
- Modify input parameters unless expected
- Use too many parameters (consider objects or builder)
- Ignore parameter validation
- Use ambiguous parameter names
- Return values through parameters (use return instead)
Common Pitfalls
- Modifying primitive parameters - changes are local
- Assuming object parameters can be reassigned - only reference copy
- Not validating null parameters - leads to NPE
- Using == for parameter comparison - use equals() for objects
- Ignoring parameter mutability - can lead to unexpected changes
Conclusion
Method parameters and arguments are the communication channels between different parts of your program:
- 🎯 Parameters define what a method needs
- 🔧 Arguments provide the actual data
- 🛡️ Validation ensures data integrity
- 🔄 Passing mechanisms affect data modification
- 🏗️ Design patterns handle complexity
Key Takeaways:
- Java is pass-by-value - always copies values/references
- Validate parameters to prevent errors
- Use descriptive names for readability
- Consider varargs for flexibility
- Apply design patterns for complex parameter sets
Mastering parameters and arguments is essential for writing robust, flexible, and maintainable Java methods!