A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

有两个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类引用默认包(未声明包名)的类呢?

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马