赛迪网 > IT技术 Java > 技术动态
  IT资讯搜索
 
IT产品搜索
[程序开发][网管世界][网络安全][数据库技术]
[操作系统][嘉宾聊天·在线访谈][活动集锦]
[精彩专题][Symantec专区][订阅IT技术周刊]
[开发论坛][网管论坛][安全论坛][数据库论坛]
[操作系统论坛][Sybase专区][IBM dW技术专区]
[病毒求助][病毒与漏洞播报][文档·源码下载]

讨论:关于Java包导入的一个奇怪问题

发布时间:2007.12.05 04:54     来源:赛迪网    作者:执木

首先新建一个目录存放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也会被自动编译。
   (责任编辑:包春林)


[ 发表评论 ] 字体[  ] [ 打印 ] [ 进入博客 ] [ 进入论坛 ]  [ 推荐给朋友 ]
  相关文章
· 最好不要重新分配被锁定对象的对象引用 (12-04) · 应用JDOM处理数据库到XML转换JSP实现 (12-04)
· 架构与模式:多线程有几种常用的编程模型 (12-04) · Java源码分析--深入探讨Iterator模式 (12-04)
· JAVA基础:用Java代码构建一个线程池 (12-04) · 教你如何在Java应用程序中访问USB设备 (12-04)
· 程序员必读:Java的多进程运行模式分析 (12-04) · Java基础:Java列表对象性能分析和测试 (12-04)
· 进阶--Java对象池技术的原理及其实现 (12-04) · J2EE基础:Servlet中如何捕获Session事件 (12-04)
  客户需求反馈表
* 姓  名:
更多资料  了解方案  认识厂商
* 单位名称:
* 联系电话:
* 电子邮件:
  赛迪推荐  
  手机·资费 ·新品·导购·评测·手机资费·宽带
手机搜索  诺基亚 N73 MOTO Z6
  IT产品 ·笔记本·台式机·服务器·打印·投影
IT产品搜索 
  IT技术 ·开发·网管·安全·数据库·操作系统
  信息化 ·热点·专题·访谈·周刊·方案案例
· 北京新规不能霸王硬上弓 网店牌照缓期执行
· 软件外包之变的新台阶: 提高全球交付能力
· ERP案例分析 SaaS带来冲击 IT服务商面临挑战
· 通方期货CRM解决方案 房地产行业CRM解决方案
  IT博客 ·曾剑秋·项立刚·Java学习·网管
  IT技术论坛 ·开发·网管·安全·数据库·系统