Bỏ qua để đến nội dung

Tham số (Parameter) và đối số (Argument)

  • Tham số (parameter): biến được khai báo trong định nghĩa phương thức
  • Đối số (argument): giá trị thực sự được truyền vào khi gọi phương thức
static int add(int a, int b) { // a, b là THAM SỐ (parameter)
return a + b;
}
public static void main(String[] args) {
int result = add(3, 5); // 3, 5 là ĐỐI SỐ (argument)
}

Java luôn truyền tham số theo giá trị (pass-by-value) - không có ngoại lệ, kể cả với đối tượng. Tuy nhiên cách nó biểu hiện khác nhau giữa kiểu nguyên thủy và kiểu tham chiếu:

Một bản sao giá trị được truyền vào - thay đổi tham số bên trong phương thức không ảnh hưởng đến biến gốc bên ngoài:

static void increment(int x) {
x = x + 1; // chỉ thay đổi bản sao cục bộ
}
public static void main(String[] args) {
int number = 5;
increment(number);
System.out.println(number); // 5 - KHÔNG đổi!
}

Một bản sao của tham chiếu (reference) được truyền vào - cả tham số và biến gốc cùng trỏ đến cùng một đối tượng trên heap. Vì vậy:

  • Thay đổi trạng thái bên trong đối tượng (qua tham chiếu) → ảnh hưởng ra ngoài
  • Gán lại tham số trỏ sang đối tượng kháckhông ảnh hưởng đến biến gốc bên ngoài
import java.util.ArrayList;
import java.util.List;
static void addItem(List<String> list) {
list.add("mới"); // sửa NỘI DUNG đối tượng mà list đang trỏ tới -> ảnh hưởng ra ngoài
}
static void reassign(List<String> list) {
list = new ArrayList<>(); // chỉ gán lại BIẾN CỤC BỘ list, không ảnh hưởng biến gốc
list.add("không thấy được từ bên ngoài");
}
public static void main(String[] args) {
List<String> items = new ArrayList<>();
items.add("ban đầu");
addItem(items);
System.out.println(items); // [ban đầu, mới] - CÓ thay đổi
reassign(items);
System.out.println(items); // [ban đầu, mới] - KHÔNG đổi, vẫn như trước
}

Java cho phép một phương thức nhận số lượng tham số không cố định bằng cú pháp ... (varargs):

static int sum(int... numbers) { // numbers được xem như một mảng int[] bên trong phương thức
int total = 0;
for (int n : numbers) {
total += n;
}
return total;
}
public static void main(String[] args) {
System.out.println(sum()); // 0
System.out.println(sum(1, 2)); // 3
System.out.println(sum(1, 2, 3)); // 6
}

Varargs phải là tham số cuối cùng trong danh sách tham số.

  • Tham số là biến khai báo trong phương thức; đối số là giá trị thực truyền vào khi gọi
  • Java luôn pass-by-value: với kiểu nguyên thủy là bản sao giá trị; với đối tượng là bản sao tham chiếu
  • Sửa nội dung đối tượng qua tham chiếu ảnh hưởng ra ngoài; gán lại tham số sang đối tượng khác thì không
  • int... numbers (varargs) cho phép nhận số lượng tham số tùy ý, phải là tham số cuối cùng