25. 【Java教程】Java 包

简介: 25. 【Java教程】Java 包

当我们的程序规模越来越大,类的数量也会随之增多,数量繁多的类会造成项目的混乱,不易于维护管理。本小节所介绍的包就是为了将类分类而产生的,我们可以使用包让程序结构更加清晰且易于管理。本小节将会学习到什么是包如何声明包包作用域以及包的命名规范等知识点。

1. 概述

1.1 什么是包

包是一个命名空间,它可以将类和接口进行分组。

从概念上讲,我们可以将包看作是计算机上的不同文件夹。例如,我们可以将图片保存在一个文件夹中,将视频保存在另一个文件夹中。

1.2 为什么需要包

正如我们在前言中所提到的,当程序规模越来越大,类的数量也会随之增多。使用包将这些类分组后,可以让类更易于查找和使用,也可以避免命名冲突,还可以控制访问。


易于查找和使用很容易理解,试想我们电脑的某一个文件夹中,存放着成百上千的各类文件,即使使用搜索功能都不能迅速定位到我们想要的文件,而将这些文件按照功能或特点分类存入到不同的文件夹下,就可以大大提高我们查找和使用的效率。对于 Java 语言的类也是同样的道理。


对于命名冲突,我们来看实际开发中的一个例子:一个 Java 工程由 3 个程序员协同开发,程序员 A 写了一个工具类 Util,程序员 B 也写了一个工具类 Util,程序员 C 既想使用 A 的 Util,又想使用 B 的 Util,这个时候可以分别将 A、B 两个人的 Util 类放入两个不同的包下,就可以解决命名冲突了。


对于控制访问,我们将在本小节的包作用域部分举例讲解。

2. 包声明

2.1 语法

在一个类中,使用关键字 package 在类的顶部声明一个包:

package service;
 
public class DemoService {
    ...
}

面的代码就表示 DemoService 类放到了 service 包下,我们也可以说:DemoServiceservice 包中声明。我们的类如果在包中声明,那么类就必须放置在源码目录下以包名称命名的子目录中。这样编译器才能在系统中找到 Java 文件。

2.2 实例

下面我们使用 IntelliJ IDEA 来演示一个简单的建包到建类的过程。


新建一个名为 mybj 的工程,之前我们已经学过如何在 IDE 中新建工程,因此这里不再截图演示。查看下图,mybj 是工程名,src 是源码目录。

首先在源码目录新建一个包,命名为 service。在 src 目录上点击鼠标右键 -> New -> Package

填入包名 service

输入 Enter 完成包的新建,此时工程结构如下:

接下来在包下面新建一个 DemoService 类。在 service 点击右键 -> New -> Java Class,输入类名称 DemoService 完成新建,此时工程结构如下:

而 IDE 也会在类的顶部自动为我们声明包:

这样就完成了一个包到类的新建。

重复以上步骤,我们接着在源码目录下新建一个 util 包,在 util 包中新建一个 DemoUtil 类。

此时,mybj 工程在物理硬盘上的文件结构为:

├── mybj
│   └── src
│       ├── service
│       │   └── DemoService.java
│       └── util
│           └── DemoUtil.java

通过上述一系列演示,我们验证了这个结论:所有的 Java 文件对应的目录层级要和包的层级保持一致。


另外,包下面也可以包含子包,子包中也可以声明类,例如,可以在上面的 service 包下新建一个 demo 包,在 demo 包下新建一个 DemoClass 类。如下代码可以看到类顶部包的声明,要使用. 分隔多个包名:


1. 
package service.demo;
2. 
3. public class DemoClass {
4. }

3. 导入包

3.1 完整类名导入

在类名前面加上包名(我们称为完整类名),就可以使用指定包中的类。例如,对与上面示例的项目结构,我们想在 DemoService 类中使用 DemoUtil 类,可以这样写:

package service;
 
public class DemoService {
    util.DemoUtil demoUtil = new util.DemoUtil();
}

如果使用同一包中的类,则不必在类前面指定包名。

3.2 import 关键字导入

上面的语法比较冗长,我们可以使用 import 关键字在文件顶部导入指定包中类,在代码中就不必指定包名来使用类了。例如,上面的代码可以改成写:

package service;
 
import util.DemoUtil;
 
public class DemoService {
    DemoUtil demoUtil = new DemoUtil();
}

Tips:如果有两个或多个类名相同,那么就不能使用 import 关键字同时导入了,此时建议使用完整类名的方式使用类。当然,实际的编码中,我们也不推荐命名多个同名类。



3.3 通配符导入

在使用 import 关键字时,可以使用通配符 * 来导入指定包下面的所有类。例如:

package service;
 
import util.*;
 
public class DemoService {
    DemoUtil demoUtil = new DemoUtil();
}

尽管它看起来非常方便,但是我们不推荐这种写法。一方面降低了代码的可读性,另外也可能导致一些问题。

还有一点需要特别提醒,java.lang 包中的所有类会都被编译器隐式导入,所以在使用诸如 SystemString 等类的时候,我们不需要手动导入。

4. 包作用域

所谓包作用域,就是没有使用访问修饰符修饰的字段和方法。同一个包中的类,可以访问包作用域的字段和方法。

例如,在 com.mybj 包下面有一个 Student 类:

package com.mybj;
 
public class Student {
 
    // 包作用域的属性
    String name;
 
    // 包作用域的方法
    void sayHello() {
        System.out.println("你好!" + name);
    }
 
}

com.mybj 包下面的 Test 类,访问 Student 类中的字段和方法:

package com.mybj;
 
public class Test {
    public static void main(String[] args) {
        Student student = new Student();
        // 操作包作用域下属性
        student.name = "Colorful";
        // 访问包作用域下的方法
        student.sayHello();
    }
}

由于 StudentTest 都属于 com.mybj 包,所以可以访问包作用域内的字段和方法。

5. 包命名规范

包名应该使用全小写字母命名,这样易于将包名与类名区分开。

为了避免名称冲突,通常建议以公司域名的倒置来确保唯一性。例如,码云笔记域名为 mybj123.com,项目的包命就应该为 com.mybj,其具体的子包可根据功能业务命名。


再举几个例子,大名鼎鼎的 Apache 软件基金会的包命名为 org.apache,Java 领域最知名开源框架 Spring 包名为 org.springframework。

6. 小结

本小节我们学习了 Java 包的定义与使用,Java 提供包的机制主要是为了类避免命名冲突。我们也知道了如何声明包、如何导入包以及包作用域的概念,实际项目的包名推荐使用域名倒置。

包的使用,除了在我们自己编写的项目中非常常见,你也可以翻阅 JDK 的源码,Java 平台按照功能将类放入了不同的包中。例如:基础的类在 java.lang 包中,用于读写的类在 java.io 包中,一些工具类放在 java.util 包中。Java 平台由成百上千的类组成,把这些类放入包中,可以使程序结构井井有条。


相关文章
|
3天前
|
XML 测试技术 数据格式
《手把手教你》系列基础篇(八十五)-java+ selenium自动化测试-框架设计基础-TestNG自定义日志-下篇(详解教程)
【7月更文挑战第3天】TestNG教程展示了如何自定义日志记录。首先创建一个名为`TestLog`的测试类,包含3个测试方法,其中一个故意失败以展示日志。使用`Assert.assertTrue`和`Reporter.log`来记录信息。接着创建`CustomReporter`类,继承`TestListenerAdapter`,覆盖`onTestFailure`, `onTestSkipped`, 和 `onTestSuccess`,在这些方法中自定义日志输出。
21 6
|
3天前
|
Java 测试技术 Apache
《手把手教你》系列基础篇(八十六)-java+ selenium自动化测试-框架设计基础-Log4j实现日志输出(详解教程)
【7月更文挑战第4天】Apache Log4j 是一个广泛使用的 Java 日志框架,它允许开发者控制日志信息的输出目的地、格式和级别。Log4j 包含三个主要组件:Loggers(记录器)负责生成日志信息,Appenders(输出源)确定日志输出的位置(如控制台、文件、数据库等),而 Layouts(布局)则控制日志信息的格式。通过配置 Log4j,可以灵活地定制日志记录行为。
18 4
|
1天前
|
XML Java 测试技术
《手把手教你》系列基础篇(八十八)-java+ selenium自动化测试-框架设计基础-Log4j 2实现日志输出-下篇(详解教程)
【7月更文挑战第6天】本文介绍了如何使用Log4j2将日志输出到文件中,重点在于配置文件的结构和作用。配置文件包含两个主要部分:`appenders`和`loggers`。`appenders`定义了日志输出的目标,如控制台(Console)或其他文件,如RollingFile,设置输出格式和策略。`loggers`定义了日志记录器,通过`name`属性关联到特定的类或包,并通过`appender-ref`引用`appenders`来指定输出位置。`additivity`属性控制是否继承父logger的配置。
|
2天前
|
XML Java 测试技术
《手把手教你》系列基础篇(八十七)-java+ selenium自动化测试-框架设计基础-Log4j 2实现日志输出-上篇(详解教程)
【7月更文挑战第5天】Apache Log4j 2是一个日志框架,它是Log4j的升级版,提供了显著的性能提升,借鉴并改进了Logback的功能,同时修复了Logback架构中的问题。Log4j2的特点包括API与实现的分离,支持SLF4J,自动重新加载配置,以及高级过滤选项。它还引入了基于lambda表达式的延迟评估,低延迟的异步记录器和无垃圾模式。配置文件通常使用XML,但也可以是JSON或YAML,其中定义了日志级别、输出目的地(Appender)和布局(Layout)。
|
2天前
|
IDE Java 测试技术
使用Java实现单元测试:JUnit教程
使用Java实现单元测试:JUnit教程
|
4天前
|
Java 测试技术 Android开发
《手把手教你》系列基础篇(八十四)-java+ selenium自动化测试-框架设计基础-TestNG日志-上篇(详解教程
【7月更文挑战第2天】TestNG是一个用于自动化测试的Java框架,提供日志记录功能。日志有两种模式:底层级详细记录每个步骤,高层级仅记录关键事件。示例代码展示了如何在测试方法中使用`Reporter.log()`记录信息,这些信息会显示在TestNG HTML报告中。文章还提及了日志显示时可能出现的编码问题及解决办法。
|
5天前
|
XML 存储 JavaScript
黑马全套Java教程(十)(二)
黑马全套Java教程(十)
6 0
|
5天前
|
IDE Java 测试技术
黑马全套Java教程(十)(一)
黑马全套Java教程(十)
10 0
|
5天前
|
存储 Java
黑马全套Java教程(九):网络编程(四)
黑马全套Java教程(九):网络编程
11 0
|
5天前
|
网络协议 Java
黑马全套Java教程(九):网络编程(三)
黑马全套Java教程(九):网络编程
8 0