参考自–《Java核心技术卷1》
包(package)
Java 使用包将类组织起来。借助包可以方便地组织自己的代码,并将自己的代码与别人提供的代码库分开管理。
标准的 Java 类库分布在多个包中,包括 java.lang
、java.util
等
使用包的主要原因是确保类名的唯一性。
1.1 类的导入
一个类可以使用所属包中的所有类,以及其他包中的共有类(public class)。
使用其他包中的共有类的方式有两种:
1)在每个类名前添加完整的包名(繁琐)
java.time.LocalDate today = java.time.LocalDate.now();
2)使用 import 语句导入包(简单、常用),也可以只导入指定的类
import java.util.*; //导入 java.util包中的所有类 import java.util.LocalDate;
......
LocalDate today = LocalDate.now();
注:有时遇到命名冲突时(两个包中有相同类名的类),需要额外注意:
例如:java.util
和 java.sql
包中都有日期(Date)类,如果只是导入这两个包,
import java.util.*;
import java.sql.*;
...
Date today; //出错
程序使用 Date 类时,就会出现编译错误(编译器无法确定程序使用的是哪一个 Date 类)。可以增加一个特定的 import 语句来解决这个问题:
import java.util.*;
import java.sql.*;
import java.util.Date; //要使用的是 java.util包的Date类
...
Date today; //OK
若两个包的 Date 类都需要使用,则可以在每个类名的前面加上完整的包名(如第一种导入包的方法)。
1.2 静态导入
import 语句不仅可以导入类,还可以导入静态(static)方法和静态域。
例如:
import static java.lang.System.*; //java.lang包是默认导入的
...
out.println("Hello"); //System.out.println
exit(0); //System.exit(0) -- 结束程序的运行
//但是,采用 System.out 或System.exit 的书写形式代码确实更加清晰
或者:
import static java.lang.Math.sqrt;
...
sqrt(2); //较 Math.sqrt(2) 简单,清晰
1.3 将类放入包中
要想将一个类放入指定包中,就必须创建这个包且将包的名字放在源文件的开头。如:
package cn.study.sample01; //类放在cn.study.sample01包中
import ...
...
public class 类{
...
}
如果源文件中没有放置 package 语句,则这个源文件中的类就会被放置到一个默认包(default package)中。默认包是一个没有名字的类。
1.4 包作用域
标记为 public 的部分可以被任意的类使用;
标记为 private 的部分只能被定义它们的类使用。
如果没有指定 public 或 private ,则这个部分(包括里面的类、方法、变量)可以被同一个包中的所有方法访问。
1.5 编译器编译时定位文件过程(路径)
Java 编译器总是在当前的目录(包)中查找文件。如果引用了一个类,而没有指出这个类所在的包,那么编译器将首先查找包含这个类的包,并查询所有的 import 指令,确定其中是否包含了被引用的包。如 源文件中包含 import 语句:
import java.util.*;
import cn.study.sample;
...
// 下面引用了Employee类
当编译器编译 Employee 类的引用时,它将试图查找 java.lang.Employee
(默认导入的包)、java.util.Employee
、cn.study.sample.Employee
和当前包中的 Employee。如果找到一个以上的类或没找的,就会产生编译错误(import 语句的次序无关紧要)。
另外,编译器在开始编译源文件时,会查看源文件是否比之前编译产生的类文件(如果源文件是第一次编译即会产生一个类文件)新。如果源文件较类文件更新(即有修改),那么源文件就会被自动地重新编译。