CodeGym /Các khóa học /JAVA 25 SELF /Lỗi khi khai báo lớp và đối tượng

Lỗi khi khai báo lớp và đối tượng

JAVA 25 SELF
Mức độ , Bài học
Có sẵn

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

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION