第27章

Java包(package)

掌握包的概念、声明语法和import语句的使用方法

学习目标

Java包的概念详解

在Java编程中,包(package)是一种重要的代码组织机制。它类似于文件系统中的文件夹,用于将相关的类和接口组织在一起,提供命名空间和访问控制功能。

命名空间

避免命名冲突:
com.example.util.StringUtils
com.company.util.StringUtils
// 两个不同的StringUtils类
  • 避免类名冲突
  • 提供唯一标识
  • 支持同名类共存
  • 便于代码管理

访问控制

包级别访问:
package com.example;

class PackageClass {  // 包级别访问
    void packageMethod() {
        // 只能在同一包中访问
    }
}
  • 包级别访问控制
  • 封装实现细节
  • 控制类的可见性
  • 增强代码安全性

代码组织

包结构示例:
com.example.ecommerce/
├── model/     # 实体类
├── service/   # 业务逻辑
├── dao/       # 数据访问
└── util/      # 工具类
  • 逻辑分组管理
  • 模块化设计
  • 便于团队协作
  • 提高代码可维护性

命名规范

标准命名:
// 推荐的包名
com.company.project.module
org.apache.commons.lang
edu.university.department

// 避免的包名
Com.Example.Util  // 大写字母
com.example.class // 关键字
  • 全小写字母
  • 点号分隔层级
  • 域名反向形式
  • 避免Java关键字

包的声明

package语句

package语句用于声明当前类所属的包,它必须是Java文件中的第一行非注释代码。

基本语法:
package com.example.util;

/**
 * 字符串工具类
 * 演示包的声明
 */
public class StringUtils {
    // 类的内容
}

重要规则:

  • package语句必须是文件的第一行非注释代码
  • 一个Java文件只能有一个package语句
  • 包名必须与目录结构完全对应
  • 如果没有package语句,类属于默认包

目录结构对应

包名必须与文件系统的目录结构完全对应:

目录结构示例:
src/
└── com/
    └── example/
        ├── util/
        │   ├── StringUtils.java    # package com.example.util;
        │   └── MathUtils.java      # package com.example.util;
        ├── model/
        │   ├── User.java           # package com.example.model;
        │   └── Product.java        # package com.example.model;
        └── ImportExample.java      # package com.example;

Import语句详解

import语句用于导入其他包中的类,使我们能够在当前类中直接使用这些类,而不需要使用完全限定名。

Import语句类型

类型 语法 说明 示例
导入单个类 import 包名.类名; 导入指定的类 import java.util.ArrayList;
导入包中所有类 import 包名.*; 导入包中的所有公共类 import java.util.*;
静态导入方法 import static 类名.方法名; 导入静态方法 import static Math.max;
静态导入所有 import static 类名.*; 导入所有静态成员 import static Math.*;

Import语句示例

完整的Import示例:
package com.example;

// 导入自定义包中的类
import com.example.model.User;
import com.example.model.Product;
import com.example.util.StringUtils;
import com.example.util.MathUtils;

// 导入Java标准库中的类
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

// 静态导入示例
import static com.example.util.MathUtils.max;
import static com.example.util.MathUtils.min;
import static java.lang.System.out;

public class ImportExample {
    public static void main(String[] args) {
        // 使用导入的类
        User user = new User("张三", 25, "zhangsan@example.com");
        List list = new ArrayList<>();
        
        // 使用静态导入的方法
        int result = max(10, 20);
        out.println("最大值: " + result);
    }
}

Import语句规则:

  • import语句位于package语句之后,类声明之前
  • 可以有多个import语句
  • 不需要导入同一包中的类
  • 不需要导入java.lang包中的类(如String、System等)
  • 静态导入允许直接使用静态方法和字段

包与访问控制

Java的访问修饰符与包密切相关,不同的访问级别决定了类、方法和字段在不同包中的可见性。

访问修饰符对比

修饰符 同一类 同一包 子类 不同包
public
protected
默认(包级别)
private
包级别访问示例:
package com.example.model;

// 包级别类 - 只能在同一包中访问
class PackagePrivateClass {
    // 包级别方法
    void packageMethod() {
        System.out.println("只能在同一包中调用");
    }
    
    // 公共方法
    public void publicMethod() {
        System.out.println("可以在任何地方调用");
    }
}

完整代码示例

以下是一个完整的包使用示例,展示了包的声明、import语句的使用和类之间的调用关系。

💻 查看完整代码 - 在线IDE体验

运行结果预览:

=== Java包和Import语句示例 ===

--- 自定义类使用示例 ---
用户信息: User{name='张三', age=25, email='zhangsan@example.com'}
产品信息: Product{name='笔记本电脑', price=5999.99, category='电子产品'}

--- 工具类使用示例 ---
原字符串: hello world
首字母大写: Hello world
反转字符串: dlrow olleh
是否为空: false

数学运算示例:
10 和 20 的最大值: 20
10 和 20 的最小值: 10
10 的平方: 100
10 是否为偶数: true

--- Java标准库使用示例 ---
水果列表: [苹果, 香蕉, 橙子]
今天的日期: 2024年01月27日

--- 静态导入使用示例 ---
15 和 25 的最大值: 25
15 和 25 的最小值: 15
这行输出使用了静态导入的out对象

包管理最佳实践

包设计和使用的最佳实践

推荐做法

1. 使用有意义的包名:
com.company.project.service
com.company.project.model
com.company.project.util
2. 按功能组织包结构:
com.example.ecommerce/
├── model/          # 实体类
├── service/        # 业务逻辑
├── dao/           # 数据访问
├── controller/    # 控制器
└── util/          # 工具类
3. 合理使用import:
// 推荐:导入具体类
import java.util.ArrayList;
import java.util.HashMap;

// 适度使用:常用包的通配符
import java.util.*;
4. 静态导入的合理使用:
// 适合:常用的静态方法
import static java.lang.Math.PI;
import static java.lang.Math.sqrt;

应该避免

1. 默认包的使用:
// 避免:没有package声明
public class MyClass {
    // ...
}
2. 包名使用大写字母:
// 错误
package Com.Example.Util;
3. 过度使用通配符导入:
// 避免:导入过多不相关的类
import java.awt.*;
import java.util.*;
import javax.swing.*;
4. 循环依赖:
// 避免:包A依赖包B,包B又依赖包A
package com.example.a;
import com.example.b.*;

package com.example.b;
import com.example.a.*;

章节总结