1. Từ khóa new
Trong Java, để tạo một đối tượng của bất kỳ lớp nào, ta dùng từ khóa new. Đây là từ “ma thuật” yêu cầu JVM: cấp phát bộ nhớ cho đối tượng mới và gọi constructor của nó.
So sánh:
Nếu lớp là bản thiết kế của một chiếc ô tô, thì new là nhà máy lắp ráp chiếc xe thật dựa trên bản thiết kế đó.
Ví dụ
Person vasya = new Person();
Điều gì đang xảy ra ở đây:
- new Person() — tạo một đối tượng mới kiểu Person (gọi constructor).
- vasya — biến lưu tham chiếu tới đối tượng được tạo.
Trông như thế nào trong bộ nhớ
Khi bạn viết Person vasya = new Person();, trong bộ nhớ sẽ được cấp phát vùng cho các trường của đối tượng (ví dụ, tên và tuổi), và biến vasya chứa địa chỉ của vùng đó — một tham chiếu.
Lưu ý:
Nếu quên viết new, biến sẽ chỉ là tham chiếu không trỏ tới đâu cả (null). Cố truy cập trường hay phương thức của “đối tượng rỗng” như vậy sẽ dẫn tới NullPointerException.
2. Gọi constructor: hoạt động thế nào?
Constructor là một phương thức đặc biệt được gọi khi tạo đối tượng và dùng để khởi tạo các trường, chuẩn bị instance sẵn sàng hoạt động.
Cú pháp
ImyaKlassa imyaPeremennoy = new ImyaKlassa(argumenty);
- Nếu lớp có constructor có tham số, bạn bắt buộc phải truyền chúng.
- Nếu là constructor không có tham số (hoặc mặc định), cặp ngoặc sẽ để trống.
Ví dụ: constructor có tham số
public class Person {
String name;
int age;
// Constructor có tham số
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
Tạo đối tượng:
Person petya = new Person("Petya", 25);
Giá trị "Petya" và 25 sẽ được gán vào các trường name và age của đối tượng mới.
Constructor không có tham số
public Person() {
this.name = "Không tên";
this.age = 0;
}
Bây giờ có thể viết:
Person mysteryMan = new Person(); // name="Không tên", age=0
3. Làm việc với đối tượng: trường và phương thức
Sau khi tạo đối tượng, bạn có thể truy cập các trường và phương thức của nó thông qua toán tử chấm (.):
petya.name = "Pyotr";
System.out.println(petya.name); // Pyotr
petya.sayHello();
Nếu trong lớp có phương thức:
public void sayHello() {
System.out.println("Xin chào, tôi tên là " + name + "!");
}
Thì lời gọi petya.sayHello(); sẽ in ra: Xin chào, tôi tên là Pyotr!
Ví dụ: lớp hoàn chỉnh
public class Person {
String name;
int age;
public Person(String name, int age) { // constructor
this.name = name;
this.age = age;
}
public void sayHello() { // method
System.out.println("Xin chào, tôi tên là " + name + "!");
}
}
Sử dụng:
Person vasya = new Person("Vasya", 30);
vasya.sayHello(); // Xin chào, tôi tên là Vasya!
4. Biến tham chiếu: là gì?
Biến kiểu lớp trong Java là tham chiếu tới đối tượng trong bộ nhớ, chứ không phải chính đối tượng.
Minh họa
Person vasya = new Person("Vasya", 30);
Person anotherVasya = vasya;
Bây giờ cả vasya và anotherVasya đều trỏ tới cùng một đối tượng trong bộ nhớ. Nếu thay đổi một trường thông qua một biến — nó cũng sẽ thay đổi khi truy cập qua biến kia:
anotherVasya.age = 31;
System.out.println(vasya.age); // 31
Điểm quan trọng:
Nếu tạo hai đối tượng khác nhau, chúng độc lập với nhau:
Person petya = new Person("Petya", 25);
Person masha = new Person("Masha", 22);
petya.age = 99;
System.out.println(masha.age); // 22 (không thay đổi!)
5. Ví dụ: tạo và sử dụng nhiều đối tượng
Hãy thêm vào ứng dụng vài đối tượng. Giả sử ta có lớp Person, và trong main ta tạo vài người rồi in lời chào của họ.
Lớp Person
public class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void sayHello() {
System.out.println("Xin chào, tôi tên là " + name + ", tôi " + age + " tuổi!");
}
}
Sử dụng trong main
public class Main {
public static void main(String[] args) {
Person vasya = new Person("Vasya", 25);
Person petya = new Person("Petya", 27);
vasya.sayHello(); // Xin chào, tôi tên là Vasya, tôi 25 tuổi!
petya.sayHello(); // Xin chào, tôi tên là Petya, tôi 27 tuổi!
// Minh họa tính độc lập của các đối tượng:
vasya.age = 100;
vasya.sayHello(); // Xin chào, tôi tên là Vasya, tôi 100 tuổi!
petya.sayHello(); // Xin chào, tôi tên là Petya, tôi 27 tuổi!
}
}
Kết quả chương trình:
Xin chào, tôi tên là Vasya, tôi 25 tuổi!
Xin chào, tôi tên là Petya, tôi 27 tuổi!
Xin chào, tôi tên là Vasya, tôi 100 tuổi!
Xin chào, tôi tên là Petya, tôi 27 tuổi!
6. Các lỗi thường gặp khi tạo đối tượng
Lỗi №1: Quên viết new
Person vasya;
vasya.name = "Vasya"; // NullPointerException!
Biến vasya không trỏ tới bất kỳ đối tượng nào (null). Cần phải tạo đối tượng bằng new.
Lỗi №2: Không truyền tham số cho constructor
Person petya = new Person(); // Lỗi biên dịch nếu không có constructor không tham số
Nếu trong lớp chỉ có constructor có tham số, bạn bắt buộc phải truyền các tham số đó khi tạo đối tượng.
Lỗi №3: Nghĩ rằng biến lưu chính đối tượng
Person a = new Person("Anya", 20);
Person b = a;
b.age = 99;
System.out.println(a.age); // 99, vì a và b là các tham chiếu tới cùng một đối tượng!
Trong Java, biến kiểu lớp luôn là tham chiếu, không phải chính đối tượng.
Lỗi №4: Thay đổi trường của một đối tượng nhưng mong đối tượng khác không đổi
Person x = new Person("X", 1);
Person y = x;
x.age = 42;
System.out.println(y.age); // 42
Nếu cần hai đối tượng độc lập — hãy tạo chúng riêng biệt!
GO TO FULL VERSION