第 7 章 / 共 20 章
包、访问控制与 import
package、四种访问修饰符、import、JAR
为什么需要包
包(package)是 Java 的命名空间,作用:避免不同库的同名类冲突、组织代码层级、配合访问修饰符做封装。每个 .java 文件第一行(如果有)必须是 package 声明,后续才是 import 与类。
// src/main/java/com/example/user/User.java
package com.example.user;
public class User {
public String name;
}目录与包名约束
包名约定:全小写、点号分层、通常以组织反向域名开头(如 com.example.myapp)。**目录结构必须与包名一致**——package com.example.user 的文件必须放在 com/example/user/ 目录下。
src/main/java/
├── com/example/
│ ├── user/
│ │ ├── User.java // package com.example.user;
│ │ └── UserService.java // package com.example.user;
│ └── order/
│ └── Order.java // package com.example.order;
└── Main.java // 默认包(不推荐)import 与 import static
import 把另一个包里的类名引入当前文件作用域,从此可用短名调用。同包内的类不需要 import。java.lang.* 是"默认导入"——String / Math / System 等都不用 import。
// Greeter.java
package com.example.app;
import java.util.List; // 单类导入(推荐)
import java.util.ArrayList;
import java.util.*; // 整包通配(一般不推荐,可读性差)
import static java.lang.Math.PI; // 静态导入:直接用 PI 而非 Math.PI
import static java.lang.Math.sqrt;
public class Greeter {
public static void main(String[] args) {
List<String> names = new ArrayList<>(Arrays.asList("Alice", "Bob"));
System.out.println(names);
System.out.println(PI);
System.out.println(sqrt(2));
}
}四种访问修饰符
Java 通过修饰符控制成员的可见性。从严到松依次是 private < 包私有(default)< protected < public。
修饰符 本类 同包 子类 其它包
-------- ---- ---- ---- ------
private ✓ ✗ ✗ ✗
(不写) ✓ ✓ ✗ ✗ ← 包私有(默认)
protected ✓ ✓ ✓ ✗
public ✓ ✓ ✓ ✓// Visibility.java
package com.example.app;
public class Visibility {
public int pub = 1; // 谁都能访问
protected int prot = 2; // 同包 + 子类
int pkg = 3; // 同包(不写修饰符)
private int priv = 4; // 只在本类
public static void main(String[] args) {
Visibility v = new Visibility();
// 本类内 4 个都能访问
System.out.println(v.pub + " " + v.prot + " " + v.pkg + " " + v.priv);
}
}顶层类与 public class 规则
一个 .java 文件可以包含多个顶层类,但其中**最多只有一个**能是 public,且 public 类的名字必须与文件名完全一致。其它非 public 顶层类只能在本文件内被使用。
// User.java <-- 文件名必须叫 User.java
package com.example.app;
public class User { // public 顶层类必须与文件同名
String name;
}
class Helper { // 包私有的辅助类,可以共存
static String tag = "util";
}JAR 包:发布与运行
JAR 本质是一个 ZIP 压缩包,里面装着 .class 文件、资源与 META-INF/MANIFEST.MF 描述。jar 命令打包,java -jar 运行。第三方库(Maven 中央仓库下载的)就是一堆 JAR。
# 假设源码已 javac 编译到 build/ 目录
$ jar cfe app.jar com.example.app.Main -C build .
# c = create, f = file 名, e = entry-point 主类
$ java -jar app.jar
Hello, World!
# 查看 jar 内容
$ jar tf app.jar
META-INF/
META-INF/MANIFEST.MF
com/example/app/Main.class
...