关于Java包导入的一个奇怪问题(www.sunxin.org)

关于 Java 包导入的一个奇怪问题
作者:孙鑫         时间: 2006-4-14 星期五
这篇文章起源于程序员之家论坛( http://www.sunxin.org )上的一个网友的提问,我对他的问题做了回答。具体网址: http://www.sunxin.org/bbs/dispbbs.asp?boardID=6&ID=12289&page=1
我感觉这个问题的答案对 Java 的初学者来说,会有一定的帮助,所以将问题和答案整理成文。
问题
首先新建一个目录存放Java源文件,或者直接在某个盘符下放置程序,例如:D:/,然后按照下面的步骤进行实验(本实验在D:/目录下操作)。
Step1:编写程序 World.java,代码如下:
package a;
 
public class World
{
    public World()
    {
    System.out.println(", World!");
 
    }
}
Step2:编写 Hello.java,代码如下:
import a.World;
 
public class Hello
{
    public static void main(String[] args)
    {
        System.out.print("Hello");
        World world = new World();
    }
}
Step3:将两个程序保存到你所建的目录下,在这里,我们将它们保存到D:/下。
Step4:编译这两个Java源文件
       先编译 World.java,执行 javac -d . World.java,在D盘生成目录a,及其中的 World.class。接下来编译 Hello.java,执行 javac Hello.java,在D盘上生成 Hello.class。
Step5:运行Hello类
       执行java Hello,输出Hello, World!目前一切正常。
Step6:修改 Hello.java
将第1行的语句“import a.World;”改为“import a.*;”,重新编译 Hello.java,出现下面的错误提示:
错误的类文件: ./ World.java
文件不包含类 World
请删除该文件或确保该文件位于正确的类路径子目录中。
        World world = new World();
        ^
Step7:根据错误提示进行下列操作
按照错误提示,删除 World.java 或者将 World.java 放到其他地方,则程序成功编译运行。
问题:
请问为何会出现Step6中的错误呢?使用 “import a.*;”导入a下所有类和接口,和使用“import a.World;”导入a包中具体的类,为何会产生上述的差异呢?
回答
当你导入一个包中所有的类时, javac在编译时并不确定你要使用的World类是a包中的类,还是其他包中的类,它会根据你机器上的CLASSPATH环境变量 的值去查找类,通常我们在CLASSPATH中会设置一个点(.),表示当前目录,如果没有CLASSPATH环境变量,那么在JDK1.4之后,默认也是查找当前目录。 javac在按照文件名(不包括后缀)来查找类,于是找到 World.java,而这个文件根本不是字节码文件,当然就报错了。当你导入一个具体的类时, javac在分析源文件时就知道了你程序中用的类是 a.World,那么它就在CLASSPATH环境变量下查找a目录下的World类,正好有,于是正确执行。
为了帮助读者对这个问题加深理解,我给大家设计了下面的操作步骤(本文是在D盘上操作):
(1)将a目录剪切到C:/下;
(2)再次执行 javac Hello.java,你会看到同样的错误。也就是证实了在出错之前, javac还没有去查找a包中的类(对于包是否存在的验证已经进行)。
(3)执行set classpath=c:/。由于你明确地设置了CLASSPATH环境变量的值,并且没有包含点(.),因此 javac不会再查找当前的目录。
(4)再次执行 javac Hello.java,你会发现成功执行。
这里面还有一个有趣的现象,如果我们将a目录下的 World.class删除,替换为 World.java,那么在编译 Hello.java时,World也会被自动编译。
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值