Java的package和import机制

转自:http://blog.sina.com.cn/s/blog_5fb298fa0100ecvx.html

一些人用了一阵子的Java,可是对于 Java 的 package 跟 import 还是不太了解。很多人以为原始码 .java文件中的 import 会让编译器把所 import 的程序通通写到编译好的 .class 档案中,或是认为 import 跟C/C++ 的 #include 相似,实际上,这是错误的观念。

  让我们先了解一下,Java 的 package 到底有何用处。

  其实,package 名称就像是我们的姓,而 class名称就像是我们的名字。package 名称有很多 . 的,就好像是复姓。比如说 java.lang.String,就是复姓java.lang,名字为 String 的类别;java.io.InputStream 则是复姓java.io,名字为InputStream 的类别。

  Java 会使用 package这种机制的原因也非常明显,就像我们取姓名一样,光是一间学校的同一届同学中,就有可能会出现不少同名的同学,如果不取姓的话,那学校在处理学生数据,或是同学彼此之间的称呼,就会发生很大的困扰。相同的,全世界的Java类别数量,恐怕比台湾人口还多,而且还不断的在成长当中,如果类别不使用套件名称,那在用到相同名称的不同类别时,就会产生极大的困扰。幸运的是,Java的套件名称我们可以自己取,不像人的姓没有太大的选择 ( 所以有很多同名同姓的 ),如果依照 Sun的规范来取套件名称,那理论上不同人所取的套件名称不会相同 ( 请参阅 "命名惯例"的相关文章 ),也就不会发生名称冲突的情况。

 可是问题来了,因为很多套件的名称非常的长,在写程序时,会多打好多字,花费不少时间,比如说在A.B.C文件下有Point和Circle两个类,现在在程序中要调用:

    A.B.C.Point  P1=newA.B.C.Point();

    A.B.C.Circle  C1=new A.B.C.Circle();

实在是不美观又麻烦.于是,Sun 想了一个办法,就是 import.就是在程序一开头的时候,说明程序中会用到那些类的路径.首先,在档案开头写:

    import A.B.C.Point;

    import A.B.C.Circle;

这两行说明了类的路径,所以当程序中提到Point就是指A.B.C.Point,而Circle就是指A.B.C.Circle,依此类推。于是原来的程序就变成:

    Point  P1=new Point();

    Circle  C1=new Circle();  

这样看起来是不是清爽多了呢?如果这些类别用的次数很多,那就更能体会到import的好处了。可是这样还是不够,因为懒是人的天性,还是会有人觉得打太多 import 了也很浪费时间,于是 Sun又提供了一个方法:

    importA.B.C.*; 意思就是,等一下程序中提到的没有姓名的类别,全都包含在A.B.C这个目录中。

  注意点:但我们在程序中经常使用System.out这个类,为什么没有importSystem.out呢,因为java.lang 这个套件实在是太常太常太常用到了,几乎没有程序不用它的,所以不管你有没有写import java.lang;,编译器都会自动帮你补上,也就是说编译器只要看到没有姓的类别,它就会自动去 java.lang里面找找看,看这个类别是不是属于这个套件的。所以我们就不用特别去import java.lang 了。

   为甚么我一开始说 import 跟 #include不同呢?因为 import 的功能到此为止,它不像 #include 一样,会将档案内容载入进来。import只是请编译器帮你打字,让编译器把没有姓的类别加上姓,并不会把别的文件的程式码写进来。如果你想练习打字,可以不要使用import,只要在用到类别的时候,用它的全部姓名来称呼它就行了(就像例子一开始那样),跟使用 import完全没有甚么两样。

 

                                先介绍Java的Package机制

基本原则:需要将类文件切实安置到其所归属之Package所对应的相对路径下。

例如:以下面程序为例:假设此Hello.java文件在D:\Java\下
package  A;
public class Hello{
  public static void main(Stringargs[]){   
    System.out.println("Hello World!");
  }
}

D:\Java>javac Hello.java  此程序可以编译通过.接着执行。
D:\Java>java Hello      但是执行时,却提示以下错误!
Exception in thread "main" java.lang.NoClassDefFoundError: hello(wrong name: A/Hello)
       at java.lang.ClassLoader.defineClass0(Native Method)
       at java.lang.ClassLoader.defineClass(ClassLoader.java:537)
       atjava.security.SecureClassLoader.defineClass(SecureClassLoader.java:123)
       atjava.net.URLClassLoader.defineClass(URLClassLoader.java:251)
       at java.net.URLClassLoader.access$100(URLClassLoader.java:55)
       at java.net.URLClassLoader$1.run(URLClassLoader.java:194)
       at java.security.AccessController.doPrivileged(Native Method)
       at java.net.URLClassLoader.findClass(URLClassLoader.java:187)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:289)
       atsun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
       atjava.lang.ClassLoader.loadClassInternal(ClassLoader.java:302)

原因是我们把生成的Hello.class规定打包在D:\Java\A文件中,必须在A文件中才能去运行。所以应该在D:\Java目录下建立一个A目录,然后把把Hello.class放在它下面,执行时,可正常通过!
D:\Java\>javaA.hello   就会输出:Hello world!

 

                             现在介绍Java的import机制

我们在D:\Java目录下建立一个JInTian.java文件,其内容如下:
import  A.Hello;
public class JInTian{
   public static voidmain(String[] args){
      Hello  Hello1=new Hello();
     }
}

D:\Java\>javacJInTian.java   编译成功!

D:\Java\>java JInTian     运行成功!

也就是你在JInTian.class中成功的引用了Hello.class这个类,是通过importA.Hello来实现的,如果你没有这句话,就会提示不能找到Hello这个类。

提示1:如果你在D:\Java目录下仍保留一个Hello.java文件的话,执行对主程序的编译命令时仍会报错!你自己可以试试呀!
提示2:如果你删除D:\Java\A\Hello.java文件的话,只留Hello.class文件,执行对主程序的编译命令时是可以通过,此时可以不需要子程序的源代码。
提出一个问题:如果把目录A剪切到其它目录,如D盘根目录下,在A目录如果执行编译和执行命令呢?
很明显,会报以下错误!当然了,前提条件是你没有设置classpath路径,其实只要没把类搜索路径设置到我这个位置就会出错的!你试试吧!



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值