有两个java类,源代码如下://没指定包名,也就是在默认包中
public class B {
  public void print(){
    System.out.println("Printed By B Class");
  }
} package com.unmi;
import B; //引用默认包中的B类
public class A {
  public static void main(String[] args) {
    B b = new B(); //在A中想要引用默认包中的B类
  }
}
 
先不说在IDE中如何编译它们以及会提示什么语法错误,只是用命令javac来编译它们,先是把它们放在同一个目录下,注意的是,虽然A.java有package unmi.com;声明,我们还是先把它放在下B.java同一目录,希望由javac命令来生成相对应的包目录。执行1.4或5.0或者是6.0的jdk所带的javac命令编译,提示的错误都是一样的C:\Documents and Settings\unmi\jbproject\test\src>C:\Java\j2sdk1.4.2_10\bin\javac -d .\ A.java
或 C:\Documents and Settings\unmi\jbproject\test\src>C:\Java\jdk1.5.0_06\bin\javac -d .\ A.java
或 C:\Documents and Settings\unmi\jbproject\test\src>C:\Java\jdk1.6.0\bin\javac -d .\ A.java错误为:A.java:3: 需要 '.'
import B; //引用默认包中的B类
        ^
1 错误如果把 A.java的 import B; 这一行注释掉,用上面的三种jdk进行编译也是出现同样的错误A.java:7: 找不到符号
符号: 类 B
位置: 类 unmi.com.A
    B b = new B();
    ^
A.java:7: 找不到符号
符号: 类 B
位置: 类 unmi.com.A
    B b = new B();
              ^
2 错误总之是在带有包名的 A类中不知道怎么去引用默认包(没有包声明)中的类B。事情到此为止也就只会提出一个疑问:Java为何不让带包名的类访问不带包名的类呢?到底有何用意,为什么要有这种限制呢?可是奇怪的事情还在发生,如果我用1.2或1.3的jdk中的javac编译器来编译上面那两个代码,却是可以编译通过的,C:\Documents and Settings\unmi\jbproject\test\src>D:\Borland\JBuilder7\jdk1.3.1\bin\javac -d .\ A.java执行后一切正常,编译出了B.class文件在正前目录下,并且在建立的com\unmi目录中生成了A.class文件,用1.2的jdk的javac编译我在SunOS 5.8操作系统下试过,也没问题的。只要能够成功编译,无论在哪种版本的JVM中执行A.class都能得到预期结果,在A.class中调用B的实例方法print()打印出 Printed By B Class。于是可以看出,这种所谓带包名的类不能访问不带包名的类只是不同版本的java编译器玩的把戏而已。回到编译器中来说,用JBuilder7能正常编译以上代码,无论工程选择何种版本的jdk(比1.3高);而用JBuilder2005或是Eclipse3.2(其他版本的Eclipse还没有试验过)则不能编译以上代码,会提示以上的语法错误,不管工程选择的是1.2或1.3的jdk也无济于事。当然把以上两代码放在工程中的话需要把A.java放到com\unmi目录中的。看来IDE也有他们自己的独特的行为,大约为启动IDE本身的JVM的版本所决定(我的猜测)。写下这个东西只要阐明一种现象(这也是我偶然用JBuilder2006打开一个JBuilder7中正常使用的工程出现错误才意识到的,而且不能轻易苟同某些人的坚持说非要用JBuilder7才行,同时他们还忽略了一个问题,生成的类既然需要拿到SunOS 5.8下的jvm1.2中运行,那何不一改JBuilder中该工程的Target JVM属性值为All Java SKDs即可),希望探求一个究竟,当然在平时编码中大可不必(并且是不应该)试图让包中的类去引用默认包中的类,为使每个类都体现出层次上的关系,应置于某一命名包中,除非一种例外,那是一个统领其他类的类,比如说Main,启动主程序的类,可以放在默认包中(不声明包名),因为它也不会被其他包中的类引用。继续重复留下那样一个问题:新的JDK的编译器为何要试图阻止从有包名的一个java类引用默认包(未声明包名)的类呢?更多内容请查看我的blog 隔叶黄莺 http://blogcn.com.cn
也是开个新贴回一下 如何在包内import包外的类? http://community.csdn.net/Expert/topic/4970/4970935.xml?temp=.1856043

解决方案 »

  1.   

    Eclipse确实如此,我好久就出现过。A中若不加package,也都一样,编译不过。但是把import去掉就可以了(与你说的不一样)。
    我也是觉得奇怪。
      

  2.   

    不写package的话,会有个默认的包,但应该不是b 和类明,所以,建议所有的类都要有package说明这个类是属于哪个包,如同windows的目录一样。
      

  3.   

    老版本的jdk难道支持?
    貌似都不支持的吧,而且发布一个包(jar),建议用package的,不然没法区分了
    比如a.jar,b.jar
    如果两个包都有默认包的一个类 A.class,将无法区分是哪个jar的所以,不推荐不用package的,package本身就有唯一区分类名的功能,有个命名规则就是域名倒过来,就是为了唯一性考虑,比如net.csdn.pkg1,而不用package无疑加大了同名冲突的问题以上纯属个人理解