1. 概述

在 Java 中,我们使用 包(package)来组织和管理相关的类、接口以及子包。这篇文章会带你快速掌握 Java 包的基本用法,包括如何创建包、如何访问包中的类型、命名规范,以及如何编译和运行打包后的类。

2. Java 包的作用

Java 包的主要作用包括:

便于查找和组织代码:逻辑相关的类放在同一个包中,方便维护和检索
避免命名冲突:不同包下可以有同名类,比如 com.baeldung.Applicationcom.example.Application
控制访问权限:结合包和 访问修饰符,可以控制类、方法等的可见性

⚠️ 如果不显式指定包,类会默认进入“默认包”(unnamed package),这在实际项目中应尽量避免。

3. 创建包

创建包非常简单,只需要在 Java 文件的 第一行 使用 package 关键字声明即可:

package com.baeldung.packages;

3.1. 包命名规范

为了避免命名冲突,Java 社区有一些约定俗成的命名规范:

  • 包名全部使用小写字母 ✅
  • 多级包名使用点号(.)分隔
  • 通常使用组织或公司的反向域名作为前缀,如 com.baeldung

例如,如果公司域名为 www.baeldung.com,包名就可以是:

com.baeldung.packages

还可以进一步细分,比如:

com.baeldung.packages.domain

3.2. 包与目录结构的关系

Java 的包结构与文件系统目录结构一一对应:

✅ 每个包对应一个目录
✅ 每个子包对应子目录

比如,包 com.baeldung.packages.domain 对应的目录结构应该是:

com/
└── baeldung/
    └── packages/
        └── domain/

大多数 IDE(如 IntelliJ IDEA、Eclipse)会自动帮你创建对应的目录结构,不用手动处理。

4. 使用包中的类

我们先定义一个类 TodoItem,放在 domain 子包中:

package com.baeldung.packages.domain;

public class TodoItem {
    private Long id;
    private String description;

    // standard getters and setters
}

4.1. 导入类(import)

如果要在其他包中使用 TodoItem,需要使用 import 导入它:

import com.baeldung.packages.domain.TodoItem;

或者导入整个包:

import com.baeldung.packages.domain.*;

✅ JDK 和第三方库的类也是通过这种方式导入的。比如:

import java.util.ArrayList;
import java.util.List;

导入之后,就可以直接使用类名了:

public class TodoList {
    private List<TodoItem> todoItems;

    public void addTodoItem(TodoItem todoItem) {
        if (todoItems == null) {
            todoItems = new ArrayList<TodoItem>();
        }
        todoItems.add(todoItem);
    }
}

4.2. 使用全限定类名

如果遇到两个类名相同但包不同的情况,比如 java.sql.Datejava.util.Date,就需要使用 全限定类名 来区分:

public class TodoList {
    private List<com.baeldung.packages.domain.TodoItem> todoItems;

    public void addTodoItem(com.baeldung.packages.domain.TodoItem todoItem) {
        if (todoItems == null) {
            todoItems = new ArrayList<com.baeldung.packages.domain.TodoItem>();
        }
        todoItems.add(todoItem);
    }

    // standard getters and setters
}

5. 编译与运行

在命令行中编译和运行包结构下的类时,需要特别注意目录结构。

假设我们有如下结构:

src/
└── com/
    └── baeldung/
        └── packages/
            ├── domain/
            │   └── TodoItem.java
            ├── TodoList.java
            └── TodoApp.java

5.1. 编译

先编译被依赖的类:

javac com/baeldung/packages/domain/TodoItem.java

再编译其他类:

javac -classpath . com/baeldung/packages/*.java

5.2. 运行

使用全限定类名执行主类:

java com.baeldung.packages.TodoApp

运行结果示例(截图):

packages

6. 总结

在这篇文章中,我们学习了 Java 包的基本概念和使用方式:

✅ 包的作用是组织代码、避免冲突、控制访问
✅ 包名要遵循规范,通常使用反向域名
✅ 包结构要与目录结构一致
✅ 使用 import 导入类,或使用全限定类名解决冲突
✅ 编译时需注意 classpath 和目录结构

完整代码示例可在 GitHub 获取:https://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-lang-syntax-2


原始标题:Guide to Java Packages | Baeldung