摘要:Java中采用package来对类进行统一管理,从而有效避免类名冲突的问题。多数开发工具习惯性地把程序放在不同package里。然而,在cmd模式下,编译和运行带有package的程序时,往往找不到类,本文针对该问题,进行分析并给出解决方法。
关键词:Java;Package;编译器;完全路径
在开发复杂的Java项目时,程序员很难确保自己选用的类名和其他程序员选择的类名完全不同。为避免类名的冲突,Java使用包(package)对类进行统一管理。
Java中的包,相当于文件中的目录,目录名即是包名,如目录结构为ch5/bean,包名即为ch5.bean;在bean目录中创建java类,并在文件的开头添加package ch5.bean;工程根目录中的java类文件未特别指定包名的情况下,即不使用package语句时,该程序默认放在缺省包中。事实上,我们在做开发的时候,习惯性地把每个类都放在不同功能的package里。
于是,常常有这样的问题出现:“为什么在MyEclipse下能够正在编译和运行的带有package的程序,在cmd模式下总是提示找不到类呢?”。今日,我们将针对“带有package的Java程序的编译和运行的问题”进行详细的剖析。
举例说明,Demo1位于缺省包,Demo2_1(有包)和Demo2_2(有包,同时还调用其他包中的类)位于包ch5当中,Demo3位于ch5.bean当中,接下来我们对以下四段代码进行分析。
第一个类Demo1:
public class Demo1 {
public static void main(String[] args) {
System.out.print(“我在缺省包下....”); }
}
第二个类Demo2_1:
package ch5;
public class Demo2 {
public static void main(String[] args) {
System.out.print(“我在package ch5....”);}}
第三个类Demo2_2:
package ch5;
import ch5.bean.Demo3;
public class Demo2 {
public static void main(String[] args) {
System.out.println(“我在package ch5下....”);
Demo3 td = new Demo3(); //调用Demo3
td.show();}}
第四个类Demo3:
package ch5.bean;
public class Demo3 {
public void show()
{System.out.print(“我是Demo3,位于ch5.bean下......”);}}
现在,假设我们将项目TestPackage放置在D盘,目录结构如下:
图1 文件目录
下面我们将在cmd模式下对程序进行编译和运行:
1)按下列命令编辑和运行Demo1,将得到正常的结果。
D:\TestPackage>javac Demo1.java
D:\TestPackage>java Demo1
我在缺省包下....
分析:该例子,不属于任何包中,也没有相互的调用关系,可以独立编译和运行。
2)按下列命令进行编辑和运行Demo2_1,程序將出现如下异常。
D:\TestPackage>ch5>javac Demo2_1.java
D:\TestPackage>ch5>java Demo2_1
Exception in thread “main” java.lang.NoClassDefFoundError:Demo2_1 (wrong na
me:ch5/Demo2_1)
分析:该类位于ch5包中,没有相互调用关系。可以进入目录ch5中编译,也可以用:D:\TestPackage> javac ch5/Demo2_1.java来对代码进行编译。但运行时,系统会在当前目录D:\TestPackage\ch5下,寻找ch5/Demo2_1,所以会出现找不到类的错误。因此,运行时必须退出到包名对应的文件夹之外,如下命令可得到对应的结果:
D:\TestPackage>java ch5/Demo2_1
我在package ch5下....
3)按下列命令进行编辑和运行Demo2_2,程序将出现如下异常。
D:\TestPackage\ch5>javac Demo2_2.java
错误1:程序包ch5.bean不存在
错误2:找不到符号Demo3;
分析:该类位于ch5包中,同时调用了ch5/bean下的Demo3。由于Demo2_2中引用了Demo3,而java本身具有类似于make的功能,因此无需对Demo3进行单独的编译,对Demo2_2进行编译时会自动生成Demo3的class文件,但是这里一定要强调的是两个文件的存放位置。Demo2_2中有句代码import ch5.bean.Demo3至关重要,这句代码,表示Demo2_2从当前目录下即D:/TestPackage/ch5,开始寻找ch5/bean/目录下的Demo3类,即D:/TestPackage/ch5/ch5/bean/Demo3.java。這时,该目录显然不存在。
为解决该问题,我们可以将复杂问题简单化,直接将Demo2_2的路径告知编译器,方法如下。
D:\TestPackage>javac ch5/Demo2_2.java
D:\TestPackage>java ch5/Demo2_2
我在package ch5下....
我是Demo3,位于ch5.bean下......
综上分析,我们不难发现,带有package的程序,最容易出现错误的地方就是编译器找不到类,本文给出的解决方法是命令行给出程序的全路径。当然,我们也可以考虑,把包的路径配置到环境变量中,然而,这种方法操作起来,过于繁琐,本文不推荐采用。
作者简介:张亚利(1981),女,河南沁阳人,汉族,硕士研究生,讲师,研究方向:计算机软件开发。