
5.2 导入类

扫码看视频
下面,我们编写一个新的类来调用Printer类的print方法,输出一些信息,如代码5.3所示。

UseImport类没有添加包名,因此在默认包中。
编译UseImport.java,会提示找不到Printer类,如图5-8所示。

图5-8 找不到Printer类
读者应该知道为什么会出现这种错误吧,并不是因为Printer.class文件不存在,而是因为Printer类的完整限定名是com.sunxin.Printer,但我们在程序中使用的类名是Printer,自然就找不到了。
修改代码5.3,使用Printer类的完整限定名来引用该类,如代码5.4所示。

再次编译UseImport.java,一切正常。
提示:(1)类中引用的其他类,其字节码文件(即.class文件)必须已经存在,且能够被找到,而不能只是存在该类的源文件(即.java文件)。(2)在需要编译多个Java源文件时,可以执行javac *.java,这不仅可以提高编译效率,还可以解决两个类互相引用的问题(因为存在谁先编译、谁后编译的问题,执行javac *.java,编译器能够很好地解决这个问题)。(3)对于有包名的多个类编译,可以执行javac-d .*.java。
这种使用完整限定名来引用类的方式未免有些复杂了,增加了编码量。要简化带包名的类的访问,我们可以使用import语句来导入包中的类,如代码5.5所示。

当使用import语句导入com.sunxin.Printer类后,在其后的代码中就可以直接使用类名Printer,有了导入语句,Java编译器就很清楚,程序中遇到的Printer类是com.sunxin.Printer。
与pacakge语句不同的是,import语句是可以有多个的,如果有多个类需要导入,就可以使用多条import语句,如代码5.6所示。


File类是Java类库中java.io包中的一个表示文件和目录路径名的类。
如果程序中需要用到一个包中大量的类,那么将类一一导入显然是很烦琐的,为此,可以用通配符“*”来代表类名,表示引入这个包中的所有类,例如:

这将导入java.io包中的所有类,之后该包中的类可以直接通过类名来引用,而不需要使用完整的限定名。
提示:(1)Java类库中的java.lang包是最核心的一个包,包含了一些Java语言的基本类与核心类,如String、Math、Integer、System和Runtime等,提供了常用的功能,这个包中的所有类都是被隐式导入的,这也是为什么我们在前面章节的代码中使用System类时无须导入该类的原因。(2)导入一个包中的所有类,并不会导入该包的子包中的类,如果使用了子包中的类,还需要单独导入。例如,“import java.awt.*; ”导入了java.awt包中的所有类,程序中需要使用ActionEvent类,而该类在java.awt.event子包中,因此也需要导入“import java.awt.event.ActionEvent;”。
但在导入多个包中的类时,如果出现类名冲突的情况,那么还是得老老实实地使用类的完整限定名。例如,假定java.util包中有一个Arrays类,com.sunxin包中也有一个Arrays类,那么在同时导入这两个类的情况下,使用Arrays类时就必须给出类的完整限定名,以明确使用的到底是哪个包中的Arrays类。

在同一个包中的类可以互相引用,无须import语句。例如,我们将UseImport类也放入com.sunxin包中,那么UseImport和Printer这两个类之间是可以直接访问的,无须导入。我们前面章节编写的类因为都在默认包中,所以都是直接引用的。那么如果一个有包的类访问默认包的类,需要导入吗?当然不需要,默认包中类的完整名字就是它的类名,无须导入!