1. Lỗi khi khai báo lớp
Thiếu bộ sửa đổi truy cập (package-private theo mặc định)
Trong Java, nếu bạn không chỉ rõ bộ sửa đổi truy cập cho lớp, thì nó chỉ truy cập được trong gói hiện tại. Điều này được gọi là package-private hoặc “truy cập theo mặc định”. Ví dụ:
// Tệp Book.java
class Book {
String title;
}
Không thể sử dụng lớp như vậy từ gói khác. Nếu bạn muốn lớp có thể truy cập ở mọi nơi (và thường đó là điều cần cho các mô hình chính), hãy dùng bộ sửa đổi public:
public class Book {
String title;
}
Tại sao điều này quan trọng?
Nếu quên đặt public, sau đó bạn sẽ tự hỏi vì sao một Library nào đó từ gói khác lại không thấy lớp của bạn.
Không khớp giữa tên lớp và tên tệp
Trong Java tên tệp chứa lớp phải trùng với tên lớp public bên trong tệp đó (phân biệt chữ hoa/thường!). Ví dụ:
// Tệp Book.java
public class Book {
// ...
}
Nếu bạn đặt tên tệp là book.java (chữ thường) hoặc, tệ hơn, BooK.java, trình biên dịch sẽ báo lỗi. Đây là một trong những lý do IDE hay “cằn nhằn” bạn khi bạn đổi tên lớp mà quên đổi tên tệp.
Lỗi cú pháp khai báo: quên ngoặc nhọn, đặt sai vị trí phương thức và trường
Java là một ngôn ngữ nghiêm ngặt. Nếu quên đâu đó một dấu ngoặc nhọn hoặc vô tình khai báo một phương thức bên trong phương thức khác (điều này là không được phép!), trình biên dịch sẽ lập tức “nhắc nhở” bạn.
Ví dụ khai báo sai:
public class User
String name; // Ôi! Thiếu ngoặc nhọn của lớp
public void printName() {
System.out.println(name);
}
}
Phiên bản đúng:
public class User {
String name;
public void printName() {
System.out.println(name);
}
}
Hãy ghi nhớ:
- Mọi trường và phương thức chỉ được khai báo bên trong ngoặc nhọn của lớp.
- Các phương thức không thể lồng nhau (một số ngôn ngữ cho phép, nhưng Java thì không!).
2. Lỗi khi tạo đối tượng
Cố dùng đối tượng trước khi khởi tạo (NullPointerException)
Lỗi phổ biến nhất — cố gắng truy cập vào một đối tượng chưa được tạo. Trong Java, các biến kiểu tham chiếu theo mặc định có giá trị null.
Ví dụ:
User user;
System.out.println(user.name); // NullPointerException!
Tại sao?
Biến user đã được khai báo nhưng chưa khởi tạo. Khi cố gắng truy cập trường hoặc phương thức — bạn sẽ nhận NPE (NullPointerException).
Cách đúng:
User user = new User();
System.out.println(user.name); // Giờ thì ổn (nếu trường không null)
Lỗi khi gọi constructor (sai tham số, thiếu constructor mặc định)
Nếu lớp chỉ có constructor có tham số, thì cố gắng tạo đối tượng không có tham số sẽ dẫn tới lỗi biên dịch.
public class Book {
String title;
public Book(String title) {
this.title = title;
}
}
Book book = new Book(); // Lỗi! Không có constructor không tham số
Giải pháp: hoặc thêm constructor không tham số, hoặc luôn truyền các giá trị cần thiết:
Book book = new Book("Java cho người mới bắt đầu");
Tạo nhiều đối tượng thay vì tái sử dụng
Đôi khi người mới tạo một đối tượng mới mỗi lần cần dùng, thay vì tái sử dụng đối tượng đã có.
Book book = new Book("Java cho người mới bắt đầu");
System.out.println(book.title);
book = new Book("Java cho người mới bắt đầu"); // Để làm gì? Đối tượng như thế đã có rồi!
System.out.println(book.title);
Đây không phải lỗi biên dịch, nhưng là dấu hiệu của phong cách code kém — bạn làm mất tham chiếu tới đối tượng cũ và tiêu tốn bộ nhớ không cần thiết.
3. Best practices: cách tránh vấp lỗi
Luôn chỉ rõ các bộ sửa đổi truy cập
Đừng ngại viết public, private hoặc protected — điều này không chỉ về bảo mật mà còn giúp mã dễ đọc hơn. IDE dĩ nhiên sẽ nhắc, nhưng tốt hơn là hình thành thói quen ngay từ đầu.
Ví dụ:
public class User {
private String name;
// ...
}
Chú ý đến cách đặt tên lớp
- Tên lớp — viết hoa chữ cái đầu, theo kiểu CamelCase: Book, LibraryUser, BookManager.
- Tên tệp — phải trùng chính xác với tên lớp.
Dùng constructor để khởi tạo các trường bắt buộc
Nếu đối tượng có những trường bắt buộc phải được điền khi tạo, hãy thêm constructor có tham số. Điều này giúp tránh lỗi trong quá trình sử dụng.
Ví dụ:
public class User {
private String name;
public User(String name) {
this.name = name;
}
}
Bây giờ không thể tạo User không có tên — trình biên dịch sẽ không cho phép.
4. Áp dụng kiến thức: xây dựng mini‑ứng dụng “Thư viện”
Hãy tiếp tục phát triển ứng dụng học tập của chúng ta. Giả sử có lớp Book và lớp Library để quản lý sách.
Ví dụ khai báo lớp đúng
// Tệp Book.java
public class Book {
private String title;
private String author;
// Constructor có tham số
public Book(String title, String author) {
this.title = title;
this.author = author;
}
// Getter
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
}
Ví dụ tạo đối tượng đúng
Book book = new Book("Java cho người mới bắt đầu", "John Doe");
System.out.println(book.getTitle() + " - " + book.getAuthor());
Ví dụ lớp quản lý
// Tệp Library.java
import java.util.ArrayList;
public class Library {
private ArrayList<Book> books = new ArrayList<>();
public void addBook(Book book) {
books.add(book);
}
public void printAllBooks() {
for (Book book : books) {
System.out.println(book.getTitle() + " - " + book.getAuthor());
}
}
}
Sử dụng trong main
public class Main {
public static void main(String[] args) {
Library library = new Library();
Book book1 = new Book("Java cho người mới bắt đầu", "John Doe");
Book book2 = new Book("OOP dễ hiểu", "Ivan Ivanov");
library.addBook(book1);
library.addBook(book2);
library.printAllBooks();
}
}
5. Minh họa và sơ đồ
Sơ đồ: khai báo cái gì ở đâu?
+-----------------------------+
| Book.java |
|-----------------------------|
| public class Book { |
| private String title; | <--- các trường (chỉ bên trong lớp)
| ... |
| public Book(...) {...} | <--- constructor (bên trong lớp)
| public String getTitle()| <--- phương thức (bên trong lớp)
| } |
+-----------------------------+
+-----------------------------+
| Main.java |
|-----------------------------|
| public class Main { |
| public static void main |
| // Tạo đối tượng |
| Book book = new Book|
| } |
+-----------------------------+
6. Phân tích các lỗi thường gặp
Lỗi 1: Không khớp giữa tên lớp và tệp
// Tệp: Libraryuser.java
public class LibraryUser { // Tên lớp có U viết hoa, còn tên tệp thì chữ thường!
// ...
}
class LibraryUser is public, should be declared in a file named LibraryUser.java
Lỗi 2: Cố dùng đối tượng chưa được khởi tạo
Book book;
System.out.println(book.getTitle()); // NullPointerException!
Lỗi 3: Quên ngoặc nhọn
public class Book
private String title; // Thông thường các trường để private cho tính đóng gói
// ...
}
';' expected
Lỗi 4: Khai báo phương thức bên trong phương thức
public class User {
public void printName() {
void sayHello() {
System.out.println("Hello!"); // Không được khai báo phương thức bên trong phương thức!
}
}
}
illegal start of type
GO TO FULL VERSION