Java包(Package):代码的"组织管理器"

Java的Package)就是代码世界的"文件夹",它帮助我们把相关的类组织在一起,让代码结构清晰、易于管理

1.为什么需要包

1.1 避免命名冲突

没有包的情况:

Java 复制代码
// 公司A的代码
class User { /* ... */ }

// 公司B的代码也用了同样的类名
class User { /* ... */ } // 冲突!无法共存

1.2 更好的组织

  • 把所有用户相关的类放在com.example.user
  • 把所有商品相关的类放在com.example.product
  • 把所有订单相关的类放在com.example.order

2.包的概念

就是一组相关类和接口的集合。它就像:

  • 学校的班级:把同一学科的学生组织在一起
  • 公司的部门:把相同职能的员工组织在一起
  • 图书馆的分类:把同类书籍放在同一书架

包的声明和命名规范

3.1 如何声明包

Java 复制代码
// 在Java文件的第一行(注释除外)声明包
package com.example.school;

public class Student {
    // 类的内容
}

3.2 包的命名规范

Java 复制代码
// 1. 使用小写字母
package com.example.mypackage;  // ✅ 正确
package Com.Example.MyPackage;  // ❌ 错误

// 2. 使用逆域名约定(最常用)
package com.google.common;      // Google的通用库
package org.apache.commons;     // Apache Commons
package java.util;              // Java标准库

// 3. 多层包名用点分隔
package com.example.project.module.submodule;

// 4. 包名要有意义
package com.shop.user;          // 用户相关
package com.shop.product;       // 产品相关  
package com.shop.order;         // 订单相关

3.3 实际示例

项目结构:

Java 复制代码
myproject/
├── src/
│   ├── com/
│   │   └── example/
│   │       └── school/
│   │           ├── Student.java
│   │           ├── Teacher.java
│   │           └── Course.java
│   └── Main.java

Student.java:

Java 复制代码
// 声明包
package com.example.school;

public class Student {
    private String name;
    private int age;
    
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public void introduce() {
        System.out.println("我是学生,我叫" + name + ",今年" + age + "岁");
    }
}

Teacher.java:

Java 复制代码
package com.example.school;

public class Teacher {
    private String name;
    private String subject;
    
    public Teacher(String name, String subject) {
        this.name = name;
        this.subject = subject;
    }
    
    public void teach() {
        System.out.println(name + "老师正在教" + subject);
    }
}

4.包的导入

4.1 导入单个类

Java 复制代码
// Main.java(不在包中,或在不同包中)
import com.example.school.Student;
import com.example.school.Teacher;

public class Main {
    public static void main(String[] args) {
        Student student = new Student("张三", 18);
        Teacher teacher = new Teacher("李老师", "数学");
        
        student.introduce();
        teacher.teach();
    }
}

4.2 导入整个包

Java 复制代码
// 导入包中的所有类
import com.example.school.*;

public class Main {
    public static void main(String[] args) {
        // 可以使用包中的所有类
        Student student = new Student("张三", 18);
        Teacher teacher = new Teacher("李老师", "数学");
        Course course = new Course("Java编程", 48);
        
        student.introduce();
        teacher.teach();
        course.showInfo();
    }
}

4.3 静态导入

Java 复制代码
import static java.lang.Math.PI;      // 导入静态常量
import static java.lang.Math.pow;     // 导入静态方法
import static java.lang.System.out;   // 导入静态成员

public class StaticImportDemo {
    public static void main(String[] args) {
        // 不用写 Math.PI,直接使用 PI
        double radius = 5.0;
        double area = PI * pow(radius, 2);
        
        // 不用写 System.out,直接使用 out
        out.println("圆的面积: " + area);
        out.println("最大值: " + Math.max(10, 20));  // 也可以混用
    }
}

4.4 不需要导入的情况

Java 复制代码
public class NoImportNeeded {
    public static void main(String[] args) {
        // 1. 同包中的类不需要导入
        // 如果这个类和Student在同一个包,可以直接使用
        
        // 2. java.lang包中的类自动导入
        String str = new String("Hello");  // java.lang.String
        Integer num = 100;                  // java.lang.Integer
        System.out.println("自动导入");      // java.lang.System
        
        // 3. 使用完全限定名(不推荐,代码冗长)
        java.util.ArrayList<String> list = new java.util.ArrayList<>();
        java.util.Date date = new java.util.Date();
        
        // 4. 处理同名冲突
        java.sql.Date sqlDate = new java.sql.Date(0);
        java.util.Date utilDate = new java.util.Date();
    }
}

5.包与目录结构

5.1 必须匹配的目录结构

规则:包名必须与目录结构完全一致!

Java 复制代码
项目结构:
src/
├── com/
│   └── example/
│       └── school/
│           ├── Student.java   (package com.example.school;)
│           └── Teacher.java   (package com.example.school;)
└── Main.java                  (没有包声明,或不同包)

编译和运行:

Java 复制代码
# 编译(在src目录下)
javac com/example/school/Student.java
javac com/example/school/Teacher.java
javac Main.java

# 运行
java Main

5.2 使用IDE的项目结构

现代IDE(如IntelliJ IDEA、Eclipse)会自动管理包结构:

Java 复制代码
myproject/
├── src/
│   └── main/
│       └── java/
│           ├── com/
│           │   └── example/
│           │       ├── school/
│           │       │   ├── Student.java
│           │       │   └── Teacher.java
│           │       └── utils/
│           │           └── StringUtil.java
│           └── Main.java
└── pom.xml 或 build.gradle

6.访问权限控制

6.1 Java的四种访问修饰符

Java 复制代码
package com.example.school;

// 公共类:所有包都可以访问
public class Student {
    // 公共字段:所有包都可以访问
    public String publicField = "公共字段";
    
    // 受保护字段:同包或子类可以访问
    protected String protectedField = "受保护字段";
    
    // 默认字段(包私有):只有同包可以访问
    String defaultField = "默认字段";
    
    // 私有字段:只有本类可以访问
    private String privateField = "私有字段";
    
    // 公共方法
    public void publicMethod() {
        System.out.println("公共方法");
        // 可以访问所有字段
        System.out.println(privateField);
    }
    
    // 受保护方法
    protected void protectedMethod() {
        System.out.println("受保护方法");
    }
    
    // 默认方法
    void defaultMethod() {
        System.out.println("默认方法");
    }
    
    // 私有方法
    private void privateMethod() {
        System.out.println("私有方法");
    }
}

6.2 访问权限总结表

修饰符 同类 同包 子类 不同包
public
protected
默认(无)
private

6.3 实际应用示例

同包访问:

Java 复制代码
// 在 com.example.school 包中
package com.example.school;

public class Course {
    // 可以访问同包的Student的所有非私有成员
    public void testAccess() {
        Student student = new Student("测试", 20);
        
        System.out.println(student.publicField);      // ✓ 可以
        System.out.println(student.protectedField);   // ✓ 可以(同包)
        System.out.println(student.defaultField);     // ✓ 可以(同包)
        // System.out.println(student.privateField);  // ✗ 错误:私有
        
        student.publicMethod();      // ✓ 可以
        student.protectedMethod();   // ✓ 可以(同包)
        student.defaultMethod();     // ✓ 可以(同包)
        // student.privateMethod();  // ✗ 错误:私有
    }
}

不同包访问:

Java 复制代码
// 在不同包中
package com.example.test;

import com.example.school.Student;

public class TestClass {
    public void testAccess() {
        Student student = new Student("测试", 20);
        
        System.out.println(student.publicField);      // ✓ 可以
        // System.out.println(student.protectedField); // ✗ 错误:不同包且非子类
        // System.out.println(student.defaultField);   // ✗ 错误:不同包
        // System.out.println(student.privateField);   // ✗ 错误:私有
        
        student.publicMethod();      // ✓ 可以
        // student.protectedMethod(); // ✗ 错误:不同包且非子类
        // student.defaultMethod();   // ✗ 错误:不同包
        // student.privateMethod();   // ✗ 错误:私有
    }
}

子类访问(跨包):

Java 复制代码
// 在不同包中创建Student的子类
package com.example.test;

import com.example.school.Student;

public class GraduateStudent extends Student {
    public GraduateStudent(String name, int age) {
        super(name, age);
    }
    
    public void testProtectedAccess() {
        // 子类可以访问父类的protected成员
        System.out.println(protectedField);  // ✓ 可以(子类)
        protectedMethod();                   // ✓ 可以(子类)
        
        // 但不能访问默认和私有成员
        // System.out.println(defaultField);  // ✗ 错误:不同包
        // System.out.println(privateField);  // ✗ 错误:私有
    }
}

七、综合示例:完整的学校管理系统

项目结构:

text

复制下载

css 复制代码
school-system/
├── src/
│   ├── com/
│   │   └── school/
│   │       ├── model/
│   │       │   ├── Person.java
│   │       │   ├── Student.java
│   │       │   ├── Teacher.java
│   │       │   └── Course.java
│   │       ├── service/
│   │       │   ├── StudentService.java
│   │       │   └── CourseService.java
│   │       ├── util/
│   │       │   └── DateUtil.java
│   │       └── Main.java
│   └── config.properties

代码实现:

Person.java(基类):

java 复制代码
package com.school.model;

// 人员基类
public class Person {
    protected String id;      // 受保护,子类可以访问
    protected String name;
    private int age;          // 私有,只有本类可以访问
    
    public Person(String id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    
    // 公共getter和setter
    public String getId() {
        return id;
    }
    
    public void setId(String id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        if (age > 0) {
            this.age = age;
        }
    }
    
    public void displayInfo() {
        System.out.println("ID: " + id + ", 姓名: " + name + ", 年龄: " + age);
    }
}

Student.java(学生类):

java 复制代码
package com.school.model;

public class Student extends Person {
    private String classId;  // 班级ID
    private double score;    // 成绩
    
    public Student(String id, String name, int age, String classId) {
        super(id, name, age);  // 调用父类构造方法
        this.classId = classId;
        this.score = 0.0;
    }
    
    // 可以访问父类的protected字段
    public String getStudentInfo() {
        return "学生[" + name + "](ID:" + id + ")";
    }
    
    // getter和setter
    public String getClassId() {
        return classId;
    }
    
    public void setClassId(String classId) {
        this.classId = classId;
    }
    
    public double getScore() {
        return score;
    }
    
    public void setScore(double score) {
        if (score >= 0 && score <= 100) {
            this.score = score;
        }
    }
    
    @Override
    public void displayInfo() {
        super.displayInfo();
        System.out.println("班级: " + classId + ", 成绩: " + score);
    }
}

Teacher.java(教师类):

java 复制代码
package com.school.model;

public class Teacher extends Person {
    private String subject;   // 教授科目
    private String title;     // 职称
    
    public Teacher(String id, String name, int age, String subject, String title) {
        super(id, name, age);
        this.subject = subject;
        this.title = title;
    }
    
    public void teach() {
        System.out.println(title + name + "正在教授" + subject);
    }
    
    // getter和setter
    public String getSubject() {
        return subject;
    }
    
    public void setSubject(String subject) {
        this.subject = subject;
    }
    
    public String getTitle() {
        return title;
    }
    
    public void setTitle(String title) {
        this.title = title;
    }
    
    @Override
    public void displayInfo() {
        super.displayInfo();
        System.out.println("科目: " + subject + ", 职称: " + title);
    }
}

StudentService.java(服务类):

java 复制代码
package com.school.service;

import com.school.model.Student;
import java.util.ArrayList;
import java.util.List;

public class StudentService {
    private List<Student> students = new ArrayList<>();
    
    // 添加学生
    public void addStudent(Student student) {
        students.add(student);
        System.out.println("添加学生: " + student.getName());
    }
    
    // 查找学生
    public Student findStudentById(String id) {
        for (Student student : students) {
            if (student.getId().equals(id)) {
                return student;
            }
        }
        return null;
    }
    
    // 显示所有学生
    public void displayAllStudents() {
        System.out.println("=== 所有学生 ===");
        for (Student student : students) {
            student.displayInfo();
        }
    }
    
    // 统计平均分
    public double calculateAverageScore() {
        if (students.isEmpty()) {
            return 0.0;
        }
        
        double total = 0.0;
        for (Student student : students) {
            total += student.getScore();
        }
        
        return total / students.size();
    }
}

DateUtil.java(工具类):

java 复制代码
package com.school.util;

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateUtil {
    // 私有构造方法,防止被实例化
    private DateUtil() {}
    
    // 获取当前日期字符串
    public static String getCurrentDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(new Date());
    }
    
    // 获取当前时间字符串
    public static String getCurrentTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        return sdf.format(new Date());
    }
    
    // 格式化日期
    public static String formatDate(Date date, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }
}

Main.java(主类):

java 复制代码
package com.school;

import com.school.model.Student;
import com.school.model.Teacher;
import com.school.service.StudentService;
import com.school.util.DateUtil;

public class Main {
    public static void main(String[] args) {
        System.out.println("=== 学校管理系统 ===");
        System.out.println("当前日期: " + DateUtil.getCurrentDate());
        System.out.println("当前时间: " + DateUtil.getCurrentTime());
        
        // 创建学生
        Student student1 = new Student("S001", "张三", 18, "一班");
        Student student2 = new Student("S002", "李四", 19, "二班");
        
        // 设置成绩
        student1.setScore(85.5);
        student2.setScore(92.0);
        
        // 创建教师
        Teacher teacher = new Teacher("T001", "王老师", 35, "数学", "高级教师");
        
        // 显示信息
        System.out.println("\n=== 人员信息 ===");
        student1.displayInfo();
        student2.displayInfo();
        teacher.displayInfo();
        
        // 教师授课
        System.out.println("\n=== 教学安排 ===");
        teacher.teach();
        
        // 使用服务类
        System.out.println("\n=== 学生管理 ===");
        StudentService studentService = new StudentService();
        studentService.addStudent(student1);
        studentService.addStudent(student2);
        studentService.displayAllStudents();
        
        // 查找学生
        System.out.println("\n=== 查找学生 ===");
        Student found = studentService.findStudentById("S001");
        if (found != null) {
            System.out.println("找到学生: " + found.getName());
        }
        
        // 统计平均分
        double average = studentService.calculateAverageScore();
        System.out.println("\n平均分: " + average);
    }
}

快速记忆口诀

  1. 包如文件夹 → 组织管理代码文件
  2. 逆域名命名com.example.project
  3. 导入需声明 → 不同包用import
  4. 访问有权限publicprotected、默认、private

最重要的三点

  1. 包是代码的组织单位 → 像文件夹整理文件一样整理类
  2. 包名必须与目录结构匹配 → 这是Java的硬性规定
  3. 合理使用访问修饰符 → 保护代码,控制可见性
相关推荐
czc6662 小时前
【项目实战】Redis+RabbitMQ+MySQL双阈值批量异步落库设计
java
尼古拉斯·纯情暖男·天真·阿玮2 小时前
[JavaEE初阶] 进程和线程的区别和联系
java·开发语言
苏小瀚2 小时前
[算法]---分治-快排和归并
java·算法·leetcode
认真敲代码的小火龙2 小时前
【JAVA项目】基于JAVA的宿舍管理系统
java·开发语言·课程设计
invicinble3 小时前
关于maven的全域理解
java·spring boot·maven
黑马源码库miui520863 小时前
JAVA成人用品商城系统源码微信小程序+h5+安卓+ios
android·java·微信小程序
杰克逊的日记3 小时前
k8s是怎么管理GPU集群的
java·容器·kubernetes·gpu
山峰哥3 小时前
现代 C++ 的炼金术:铸就高性能与高可维护性的工程实践
java·开发语言·前端·数据结构·c++