1. 声明类时的错误
缺少访问修饰符(默认是 package-private)
在 Java 中,如果你没有显式为类声明访问修饰符,它就只在当前包内可见。这称为 package-private,也就是“默认访问权限”。例如:
// 文件 Book.java
class Book {
String title;
}
这样的类不能在其他包中使用。如果你希望类在各处都可见(对核心模型通常就是这样),请使用 public 修饰符:
public class Book {
String title;
}
为什么这很重要?
如果忘了加 public,来自其他包的某个 Library 就看不到你的类。
类名与文件名不一致
在 Java 中,含有类的文件名必须与该文件中的 public 类名完全一致(区分大小写)。例如:
// 文件 Book.java
public class Book {
// ...
}
如果你把文件命名为 book.java(小写首字母),或者更糟的是 BooK.java,编译器会报错。这也是为什么当你重命名了类却忘了重命名文件时,IDE 会不断提醒你的原因之一。
声明语法错误:漏写花括号、方法和字段的位置不正确
Java 是一门严格的语言。如果遗漏了某个花括号,或是不小心把方法声明在另一个方法内部(这是不允许的!),编译器会立刻指出问题。
错误示例:
public class User
String name; // 哎呀!缺少类的大括号
public void printName() {
System.out.println(name);
}
}
正确写法:
public class User {
String name;
public void printName() {
System.out.println(name);
}
}
请记住:
- 所有字段和方法都必须声明在类的花括号内部。
- 方法不能彼此嵌套(有些语言允许嵌套方法,但 Java 不允许)。
2. 创建对象时的错误
在初始化之前尝试使用对象(NullPointerException)
最常见的错误就是尝试访问一个尚未创建的对象。在 Java 中,引用类型变量默认值为 null。
示例:
User user;
System.out.println(user.name); // NullPointerException!
原因?
变量 user 只是声明了,但尚未初始化。一旦尝试访问其字段或方法,就会得到 NPE(NullPointerException)。
正确做法:
User user = new User();
System.out.println(user.name); // 现在没问题(如果字段不是 null)
调用构造器时的错误(参数不匹配、缺少无参构造器)
如果类只有带参数的构造器,那么尝试不传参数创建对象会导致编译错误。
public class Book {
String title;
public Book(String title) {
this.title = title;
}
}
Book book = new Book(); // 错误!没有无参构造器
解决方案: 要么添加无参构造器,要么始终传入所需的参数:
Book book = new Book("Java 入门教程");
重复创建对象而不是复用
有时新手每次需要访问对象时都会创建一个新对象,而不是复用已经创建的对象。
Book book = new Book("Java 入门教程");
System.out.println(book.title);
book = new Book("Java 入门教程"); // 为什么?之前已经有同样的对象了!
System.out.println(book.title);
这不是编译错误,但属于不良风格——你会丢失对旧对象的引用并浪费内存。
3. 最佳实践:如何避免踩坑
始终显式声明访问修饰符
别偷懒,写上 public、private 或 protected —— 这不仅关乎安全性,也关系到代码可读性。IDE 当然会提示,但最好一开始就养成习惯。
示例:
public class User {
private String name;
// ...
}
注意类的命名
- 类名首字母大写,采用 CamelCase 风格:Book、LibraryUser、BookManager。
- 文件名必须与类名完全一致。
使用构造器初始化必填字段
如果对象存在字段必须在创建时赋值,请添加带参数的构造器。这能在使用阶段避免错误。
示例:
public class User {
private String name;
public User(String name) {
this.name = name;
}
}
现在无法创建没有名字的 User —— 编译器不会允许。
4. 应用所学:构建“小型应用:图书馆”
让我们继续完善我们的教学应用。假设有类 Book 和类 Library,用于管理图书。
类的正确声明示例
// 文件 Book.java
public class Book {
private String title;
private String author;
// 带参数的构造器
public Book(String title, String author) {
this.title = title;
this.author = author;
}
// Getter
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
}
正确的对象创建示例
Book book = new Book("Java 入门教程", "约翰·多伊");
System.out.println(book.getTitle() + " - " + book.getAuthor());
管理类示例
// 文件 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());
}
}
}
在 main 中使用
public class Main {
public static void main(String[] args) {
Library library = new Library();
Book book1 = new Book("Java 入门教程", "约翰·多伊");
Book book2 = new Book("面向对象入门", "Ivan Ivanov");
library.addBook(book1);
library.addBook(book2);
library.printAllBooks();
}
}
5. 插图与示意图
示意图:该在哪里声明什么?
+-----------------------------+
| Book.java |
|-----------------------------|
| public class Book { |
| private String title; | <--- 字段(只能在类内部)
| ... |
| public Book(...) {...} | <--- 构造器(在类内部)
| public String getTitle()| <--- 方法(在类内部)
| } |
+-----------------------------+
+-----------------------------+
| Main.java |
|-----------------------------|
| public class Main { |
| public static void main |
| // 创建对象 |
| Book book = new Book|
| } |
+-----------------------------+
6. 常见错误解析
错误 1:类名与文件名不一致
// 文件:Libraryuser.java
public class LibraryUser { // 类名的 U 为大写,但文件名是小写!
// ...
}
class LibraryUser is public, should be declared in a file named LibraryUser.java
错误 2:尝试使用未初始化的对象
Book book;
System.out.println(book.getTitle()); // NullPointerException!
错误 3:遗忘花括号
public class Book
private String title; // 字段通常设为 private 以实现封装
// ...
}
';' expected
错误 4:在方法内部声明方法
public class User {
public void printName() {
void sayHello() {
System.out.println("Hello!"); // 不能在方法内部声明方法!
}
}
}
illegal start of type
GO TO FULL VERSION