package用法
2015-08-25 17:36
555 查看
java应用程序文件
这个说法是我自己抽象出来的,指的是一般的组织在package中的所有文件。
大体分成这三种:
1,java程序源文件,扩展名为.java。
2,编译好的java类文件,扩展名为.class。
3,其他文件,除了以上的,就是资源文件。
例如图片文件,xml文件,mp3文件
等等等等都可以组织在package之中。(你当然也可以把一部电影放在package里面,当然
不提倡这样做)
package干吗用?
package就是组织文件的一种方式。
最大的作用就是组织java类文件。
成千上万的class文件,总难免重名吧,即便不重名,那么多你记得住么?当然要分门别类
的组织起来方便你随时取用吧,这个就是package最大的作用。
package是个什么东西?
package本身是一个比较抽象的逻辑概念,它的宗旨是将东西组织在一棵树里面,就好像
linux的文件系统一样,它有一个根,然后从根开始有目录和文件,然后目录中也可以有
目录。而实现的时候是怎样的呢?是利用文件系统的目录结构或者利用压缩文件中的目录
结构来组织的。
package怎么实现的?
首先讲其最重要的应用——组织源代码。
我们知道java源代码的基本单元是一个.java文本文件。
一个.java文件可以包含一个public类和无数包级类,
默认什么访问修饰都没有的类就是一个包级类。这种类只能在本package中使用。
当然了,类当中还可以有类,名唤内隐类,内隐类的访问修饰就可以是protected
或者甚至是private了。
好,那么何谓本package呢?
当你在源代码的最开头(当然,注释可以放在更开头的位置)不写package语句的话,那么
当前编译单元中的所有编译出来的类就只能够放在package的"/"上,这种package我们叫做
default package。一般我们写个HelloWorld或者简单调几个api实现个小功能的话,一般
采用这种“不打包”似的default package就可以了。
但是,当你的类开始泛滥起来的时候,你就必须考虑给类打个包放在某个package中了。
方法很简单,在所有代码开始之前写一句
package 包名;
即可。
包名是用"."间隔的字符串,一般能够当作文件名的字符串就能用到这里来。
比如
package aaa.bbb.ccc;
意味着这个编译单元所编译出来的class都必须放在/aaa/bbb/ccc这个目录之下。
否则这种类就无法正常使用,正是这种机制保证了类的严格组织。
实际上,当你在编译一些有package语句的编译单元的时候,如果你使用的是命令行的话,
应该使用-d参数让编译器自己生成目录结构,实际上你的.java就应该放在这种目录结构
之中。我举个非常简单的例子,有个人写了这么两个.java文件。
/* A.java */
package aaa.bbb.ccc;
public class A{
B b=new B();
}
/* B.java*/
package aaa.bbb.ccc;
public class B{}
然后这个人就把这两个文件就放在当前目录之下,然后javac A.java,
然后傻眼。
说找不到B,怎么找不到呢?
为什么找不到呢,不是在一个package里面吗?
对,是在一个package里面,但是B.java必须放在当前目录/aaa/bbb/ccc下面才可用,
当javac编译A.java的时候,它发现当前所在的包是aaa.bbb.ccc,然后需要一个B类,
没有B.class,就要去找B.java,而B.java的package语句和自己所在目录结构不符,没法
使用,所以就傻眼了。
这个人就知道了把B.java放到当前目录/aaa/bbb/ccc里面,嘿,编译通过了。
没错,生成了A.class,但是A.class还是不可用的,因为它不在它应该在的地方。
我们又必须将它放到它应该在的地方,它才能好好运作。
那你说我把A.java也放在当前目录/aaa/bbb/ccc里面,然后
javac aaa.bbb.ccc.A.java
漂亮吧?
不行,为什么?因为javac接受的参数是一个文件系统的文件名,javac命令行中的参数
只能是一个完整的路径名。
那我把A.java放在当前目录/aaa/bbb/ccc里面,然后
javac aaa/bbb/ccc/A.java
这下好了吧,恩,差不多,但是生成的class还是直接丢在了源代码目录之下
最好是
javac -d bin aaa/bbb/ccc/A.java
这样就会在当前目录的bin目录下看到完整的目录结构以及放置妥当的class文件。
package与classpath不得不说的事
讲了半天还是觉得不太清楚package的"/"到底在哪里,在当前目录吗?
如果不知道package的"/"在哪里,那那些package中的文件在哪里就更无从得知了。
回答很简单,package的"/"在classpath中。
头痛了,package没有搞懂的,classpath一般也不会很懂。
没事,classpath说白了就是一堆path,这些该死的path有的指向一个目录,有的指向一个
文件(只能是zip或者jar两种,当然更保险的话还是用jar比较好)。
对于java虚拟机而言,它并不想过问这些path的八卦,它所做的是一视同仁!
它要的是所有这些path中的内容,对,对它而言,它不在乎内容是来自一个目录还是来自
一个文件,总而言之,所有的这些东西在他眼里都一样。就好像它空出一块地方,把所有
的文件解压,把所有的目录中的内容保留目录结构的送入相应位置,形成一套它自己感
兴趣的package组织方式。它要的就是这种方式来访问。
所以我可以在a.jar中有一个目录结构aaa/bbb/ccc/A.class,然后在b.jar中也有一个同样
的目录结构aaa/bbb/ccc/B.class。当我把这两个文件都放在classpath中的时候,
对虚拟机而言,这个A.class和这个B.class就是放在同一个package中的。
前面的那个实践也透视了这一点,实际上编译A.java的时候,是在classpath中寻找class
文件的,找不到,则会在sourcepath中寻找其源代码文件(不设定的话,sourcepath就是等
于classpath),当我们把B.java放在当前目录中合适的目录结构中的时候,它就会找到
这个文件并将它编译,然后进行使用。因为当前目录"."是在classpath中的。
原则就是,对java而言,它是忽略文件系统细节的,它要求的只是自己的classpath
中按照约定存放的资源。
(以上classpath对应的classloader是app classloader)
import干吗用的?
java几乎所有的api都是用java语言本身写成的,是的,那些你所经常使用的String,
HashSet,HashMap等等这些类都是用java语言写成的。
这些类的制作是我们也可以来做的事情,他们同样是写出一个个java文件,打上不同的
package,然后编译好,最后压缩一下,成为jre里面的dt.jar之类的文件,变成了我们常
常调用的库。
有的人以为,当我们写下import java.util.*;之前,我们的这些库就是“不可达”的,
而当我们写下了import java.util.*之后,我们所需要的那个库文件就会被某种不知道的
机制加入到我们的工程。
错!这些人是纯粹打死不看书的想当然类型,只在乎自己的意象,不在乎其所以然。
不管你写还是不写import语句,对当前外部的编译和执行环境都不会有任何的影响。
即便你不写import java.util.*;
你照样可以用java.util.HashMap来调用系统api,根本不用做更多的事情。
这里我不得不再提一次,不要把dt.jar放到CLASSPATH环境变量中,它已经在classpath中
了,而且此举常常让初学者丢掉了默认在classpath中的"."当前目录,让他们一番热情学
java写helloworld的火焰被一盆水扑灭。
import有啥用的呢?
它只不过是一种让你少打点字的方法,就跟c++的名称空间的using语句功能一样,就是暴
露那个package下面所有的类,写代码的时候就可以直接写类名,而不用写下完整的
包名.类名,仅此而已。
不得不提的是,*仅仅代表类名,不负责以下更深层次中各级目录中的东西。
import java.*;实际上没有暴露任何类,因为没有类是打在这个包里面的。它没有
暴露java.util.*,也没有暴露java.sql.*等等,它仅仅暴露了java目录下面所有的类。
打包成jar文件
一般的打包成jar文件,除了将目录结构压缩存储在一个zip格式但是扩展名比较畸形的
文件中之外没有做任何事情。
jar文件可以用任何能够解压zip的工具来解压,如果你讨厌使用jar命令行,你甚至可以
直接使用winrar来压缩,然后改个名字即可。
当然了,jar文件也有别的用处,比如“可直接执行的jar”。
“可直接执行的jar”跟“不可直接执行的jar”的区别仅仅在于它多了一个配置文件在
jar文件中,这个文件中指出了一个完整的类名,告诉java.exe或者javaw.exe,main方法
这个类里面而已。
欲知道更多关于jar文件的用法,请参考精华区。
贴二——package从实践到理论:
package就是catalog,所谓目录册。
什么是目录册呢?比较抽象的说,就是让你快速定位一个东西的册子。
比如电话簿,比如字典,比如搜索引擎。
java中,主要是class文件,当然也可以是任何别的文件,就是通过package来组织的。
package有点类似一个虚拟的文件系统,可以将所有的东西组织在树形结构之中。
这有一个根"/",也就是我们什么package语句都不写的情况下class文件所应该处的位置。
直接赤裸裸放在classpath中的东西都是放在"/"下面,然后如果有package语句,则这个
class文件或者java源代码文件都要放在和package语句中包名对应的目录结构之中。
1,什么都别说,先跟着我来做一把
我们先找一个目录,比如C:\myjob
然后我们建立两个目录,一个叫做src,一个叫做bin
C:\myjob>md src
C:\myjob>md bin
C:\myjob>dir
驱动器 C 中的卷是 LIGHTNING
卷的序列号是 3DD1-83D9
C:\myjob 的目录
2005-12-25 14:33 <DIR> .
2005-12-25 14:33 <DIR> ..
2005-12-25 14:34 <DIR> src
2005-12-25 14:34 <DIR> bin
0 个文件 0 字节
4 个目录 305,123,328 可用字节
C:\myjob>
然后我们在src目录中去写程序
C:\myjob>cd src
C:\myjob\src>
我们写这么4个java文件
////A.java
package com.lightning;
public class A{
{System.out.println("com.lightning.A");}
}
////B.java
package com.lightning;
public class B{
{System.out.println("com.lightning.B");}
}
////C.java
package com;
public class C{
{System.out.println("com.C");}
}
////Test.java
package net.test;
import com.lightning.*;
import com.*;
public class Test{
public static void main(String[] args)
{
new A();new B();new C();
System.out.println("net.test.Test");
}
}
写好之后就是这样
C:\myjob\src>dir
驱动器 C 中的卷是 LIGHTNING
卷的序列号是 3DD1-83D9
C:\myjob\src 的目录
2005-12-25 14:34 <DIR> .
2005-12-25 14:34 <DIR> ..
2005-12-25 14:39 86 A.java
2005-12-25 14:40 86 B.java
2005-12-25 14:42 194 Test.java
2005-12-25 14:43 68 C.java
4 个文件
这个说法是我自己抽象出来的,指的是一般的组织在package中的所有文件。
大体分成这三种:
1,java程序源文件,扩展名为.java。
2,编译好的java类文件,扩展名为.class。
3,其他文件,除了以上的,就是资源文件。
例如图片文件,xml文件,mp3文件
等等等等都可以组织在package之中。(你当然也可以把一部电影放在package里面,当然
不提倡这样做)
package干吗用?
package就是组织文件的一种方式。
最大的作用就是组织java类文件。
成千上万的class文件,总难免重名吧,即便不重名,那么多你记得住么?当然要分门别类
的组织起来方便你随时取用吧,这个就是package最大的作用。
package是个什么东西?
package本身是一个比较抽象的逻辑概念,它的宗旨是将东西组织在一棵树里面,就好像
linux的文件系统一样,它有一个根,然后从根开始有目录和文件,然后目录中也可以有
目录。而实现的时候是怎样的呢?是利用文件系统的目录结构或者利用压缩文件中的目录
结构来组织的。
package怎么实现的?
首先讲其最重要的应用——组织源代码。
我们知道java源代码的基本单元是一个.java文本文件。
一个.java文件可以包含一个public类和无数包级类,
默认什么访问修饰都没有的类就是一个包级类。这种类只能在本package中使用。
当然了,类当中还可以有类,名唤内隐类,内隐类的访问修饰就可以是protected
或者甚至是private了。
好,那么何谓本package呢?
当你在源代码的最开头(当然,注释可以放在更开头的位置)不写package语句的话,那么
当前编译单元中的所有编译出来的类就只能够放在package的"/"上,这种package我们叫做
default package。一般我们写个HelloWorld或者简单调几个api实现个小功能的话,一般
采用这种“不打包”似的default package就可以了。
但是,当你的类开始泛滥起来的时候,你就必须考虑给类打个包放在某个package中了。
方法很简单,在所有代码开始之前写一句
package 包名;
即可。
包名是用"."间隔的字符串,一般能够当作文件名的字符串就能用到这里来。
比如
package aaa.bbb.ccc;
意味着这个编译单元所编译出来的class都必须放在/aaa/bbb/ccc这个目录之下。
否则这种类就无法正常使用,正是这种机制保证了类的严格组织。
实际上,当你在编译一些有package语句的编译单元的时候,如果你使用的是命令行的话,
应该使用-d参数让编译器自己生成目录结构,实际上你的.java就应该放在这种目录结构
之中。我举个非常简单的例子,有个人写了这么两个.java文件。
/* A.java */
package aaa.bbb.ccc;
public class A{
B b=new B();
}
/* B.java*/
package aaa.bbb.ccc;
public class B{}
然后这个人就把这两个文件就放在当前目录之下,然后javac A.java,
然后傻眼。
说找不到B,怎么找不到呢?
为什么找不到呢,不是在一个package里面吗?
对,是在一个package里面,但是B.java必须放在当前目录/aaa/bbb/ccc下面才可用,
当javac编译A.java的时候,它发现当前所在的包是aaa.bbb.ccc,然后需要一个B类,
没有B.class,就要去找B.java,而B.java的package语句和自己所在目录结构不符,没法
使用,所以就傻眼了。
这个人就知道了把B.java放到当前目录/aaa/bbb/ccc里面,嘿,编译通过了。
没错,生成了A.class,但是A.class还是不可用的,因为它不在它应该在的地方。
我们又必须将它放到它应该在的地方,它才能好好运作。
那你说我把A.java也放在当前目录/aaa/bbb/ccc里面,然后
javac aaa.bbb.ccc.A.java
漂亮吧?
不行,为什么?因为javac接受的参数是一个文件系统的文件名,javac命令行中的参数
只能是一个完整的路径名。
那我把A.java放在当前目录/aaa/bbb/ccc里面,然后
javac aaa/bbb/ccc/A.java
这下好了吧,恩,差不多,但是生成的class还是直接丢在了源代码目录之下
最好是
javac -d bin aaa/bbb/ccc/A.java
这样就会在当前目录的bin目录下看到完整的目录结构以及放置妥当的class文件。
package与classpath不得不说的事
讲了半天还是觉得不太清楚package的"/"到底在哪里,在当前目录吗?
如果不知道package的"/"在哪里,那那些package中的文件在哪里就更无从得知了。
回答很简单,package的"/"在classpath中。
头痛了,package没有搞懂的,classpath一般也不会很懂。
没事,classpath说白了就是一堆path,这些该死的path有的指向一个目录,有的指向一个
文件(只能是zip或者jar两种,当然更保险的话还是用jar比较好)。
对于java虚拟机而言,它并不想过问这些path的八卦,它所做的是一视同仁!
它要的是所有这些path中的内容,对,对它而言,它不在乎内容是来自一个目录还是来自
一个文件,总而言之,所有的这些东西在他眼里都一样。就好像它空出一块地方,把所有
的文件解压,把所有的目录中的内容保留目录结构的送入相应位置,形成一套它自己感
兴趣的package组织方式。它要的就是这种方式来访问。
所以我可以在a.jar中有一个目录结构aaa/bbb/ccc/A.class,然后在b.jar中也有一个同样
的目录结构aaa/bbb/ccc/B.class。当我把这两个文件都放在classpath中的时候,
对虚拟机而言,这个A.class和这个B.class就是放在同一个package中的。
前面的那个实践也透视了这一点,实际上编译A.java的时候,是在classpath中寻找class
文件的,找不到,则会在sourcepath中寻找其源代码文件(不设定的话,sourcepath就是等
于classpath),当我们把B.java放在当前目录中合适的目录结构中的时候,它就会找到
这个文件并将它编译,然后进行使用。因为当前目录"."是在classpath中的。
原则就是,对java而言,它是忽略文件系统细节的,它要求的只是自己的classpath
中按照约定存放的资源。
(以上classpath对应的classloader是app classloader)
import干吗用的?
java几乎所有的api都是用java语言本身写成的,是的,那些你所经常使用的String,
HashSet,HashMap等等这些类都是用java语言写成的。
这些类的制作是我们也可以来做的事情,他们同样是写出一个个java文件,打上不同的
package,然后编译好,最后压缩一下,成为jre里面的dt.jar之类的文件,变成了我们常
常调用的库。
有的人以为,当我们写下import java.util.*;之前,我们的这些库就是“不可达”的,
而当我们写下了import java.util.*之后,我们所需要的那个库文件就会被某种不知道的
机制加入到我们的工程。
错!这些人是纯粹打死不看书的想当然类型,只在乎自己的意象,不在乎其所以然。
不管你写还是不写import语句,对当前外部的编译和执行环境都不会有任何的影响。
即便你不写import java.util.*;
你照样可以用java.util.HashMap来调用系统api,根本不用做更多的事情。
这里我不得不再提一次,不要把dt.jar放到CLASSPATH环境变量中,它已经在classpath中
了,而且此举常常让初学者丢掉了默认在classpath中的"."当前目录,让他们一番热情学
java写helloworld的火焰被一盆水扑灭。
import有啥用的呢?
它只不过是一种让你少打点字的方法,就跟c++的名称空间的using语句功能一样,就是暴
露那个package下面所有的类,写代码的时候就可以直接写类名,而不用写下完整的
包名.类名,仅此而已。
不得不提的是,*仅仅代表类名,不负责以下更深层次中各级目录中的东西。
import java.*;实际上没有暴露任何类,因为没有类是打在这个包里面的。它没有
暴露java.util.*,也没有暴露java.sql.*等等,它仅仅暴露了java目录下面所有的类。
打包成jar文件
一般的打包成jar文件,除了将目录结构压缩存储在一个zip格式但是扩展名比较畸形的
文件中之外没有做任何事情。
jar文件可以用任何能够解压zip的工具来解压,如果你讨厌使用jar命令行,你甚至可以
直接使用winrar来压缩,然后改个名字即可。
当然了,jar文件也有别的用处,比如“可直接执行的jar”。
“可直接执行的jar”跟“不可直接执行的jar”的区别仅仅在于它多了一个配置文件在
jar文件中,这个文件中指出了一个完整的类名,告诉java.exe或者javaw.exe,main方法
这个类里面而已。
欲知道更多关于jar文件的用法,请参考精华区。
贴二——package从实践到理论:
package就是catalog,所谓目录册。
什么是目录册呢?比较抽象的说,就是让你快速定位一个东西的册子。
比如电话簿,比如字典,比如搜索引擎。
java中,主要是class文件,当然也可以是任何别的文件,就是通过package来组织的。
package有点类似一个虚拟的文件系统,可以将所有的东西组织在树形结构之中。
这有一个根"/",也就是我们什么package语句都不写的情况下class文件所应该处的位置。
直接赤裸裸放在classpath中的东西都是放在"/"下面,然后如果有package语句,则这个
class文件或者java源代码文件都要放在和package语句中包名对应的目录结构之中。
1,什么都别说,先跟着我来做一把
我们先找一个目录,比如C:\myjob
然后我们建立两个目录,一个叫做src,一个叫做bin
C:\myjob>md src
C:\myjob>md bin
C:\myjob>dir
驱动器 C 中的卷是 LIGHTNING
卷的序列号是 3DD1-83D9
C:\myjob 的目录
2005-12-25 14:33 <DIR> .
2005-12-25 14:33 <DIR> ..
2005-12-25 14:34 <DIR> src
2005-12-25 14:34 <DIR> bin
0 个文件 0 字节
4 个目录 305,123,328 可用字节
C:\myjob>
然后我们在src目录中去写程序
C:\myjob>cd src
C:\myjob\src>
我们写这么4个java文件
////A.java
package com.lightning;
public class A{
{System.out.println("com.lightning.A");}
}
////B.java
package com.lightning;
public class B{
{System.out.println("com.lightning.B");}
}
////C.java
package com;
public class C{
{System.out.println("com.C");}
}
////Test.java
package net.test;
import com.lightning.*;
import com.*;
public class Test{
public static void main(String[] args)
{
new A();new B();new C();
System.out.println("net.test.Test");
}
}
写好之后就是这样
C:\myjob\src>dir
驱动器 C 中的卷是 LIGHTNING
卷的序列号是 3DD1-83D9
C:\myjob\src 的目录
2005-12-25 14:34 <DIR> .
2005-12-25 14:34 <DIR> ..
2005-12-25 14:39 86 A.java
2005-12-25 14:40 86 B.java
2005-12-25 14:42 194 Test.java
2005-12-25 14:43 68 C.java
4 个文件
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- [原创]java局域网聊天系统