通过学习视频,看到创建包的时候一直是先写类及定义包名,才进行创建目录,并且手动将class文件放入对应包内,这样是不是很费事?就不能自动完成吗?
class文件位置
首先先来了解下包的运行。前面我已经提到了包需要对应的calss文件,其他java文件调用时,必须引入对应包名及class文件名才能正确实现调用。
然后再解决必须只能手动移动class问价吗?可以进行一次尝试,在一个目录里创建一个java文件,并在那个目录里生成class文件,然后其它目录进行调用。
假设将“com.Test”作包名,在里面创建类Bird,并生成对应的class文件:Bird.class。然后其他类调用它,测试是否成功:
import com.Dongle.*;//引用包内文件
import com.Test.*;//引用Bird文件
public class Dog {
public static void main(String[] args) {
Cat c = new Cat();
Bird b =new Bird();
}
}
成功与否,只能先通过编译了。编译结果:
这是什么原因呢?看不懂,那么回想一下哪里可能不对呢?首先,记得加入包或创建包的时候需要在开头写入包名,加上试试看:
package com.Test;
public class Bird {
}
运行结果证明:
我的猜想是对的,可以直接在对应包内写,但是还是一定要将包名先声明,这是必须的!
这也证明我不需要在其它地方写类,然后再将class文件手动移动了,这样我们可以直接在包内操作!
包引用
到这里,我需要在说明一点,也是非常重要的一点:包的声明,决定文件被使用的范围。例如上面的Bird.java文件,声明的是包:com.Test,那么Bird被使用的范围只能是TestPackage文件夹中的文件。比如Dog是TestPackage\com\Tracy文件夹下的,我们才可以调用,同样在TestPackage下的一样可以调用。但是,如果超出TestPackage文件夹的,则就会编译出错:
换句话说就是找不到包及包内文件。这就是说如果超出包的上一级目录文件就不能被调用了。那么该如何解决这个问题呢?我们总不能需要调用就只能在包的父目录里创建文件吧,如果是调用多个不同包的文件(class文件)呢?这时候就需要用到对包进行处理了:将包压缩成jar文件,就可以在任何地方进行调用了。
生成jar文件
首先我们可以看看jar都有哪些操作,通过输入jar,我们能了解jar的相关操作
通过上面的解释,以及视频上说的“jar -cvf 包名 *.*”,尝试了一番,然后就发现了问题:
提示说没有这个文件或目录,然后和视频比了又比,就是没有发现哪里有问题:
这可有点急啊,难道说视频也有错误?不可能啊,都这么多年了,要是有错肯定被指出来了。那么到底是哪里的问题呢?百度了一番,找到了一篇相关的文章: java中jar命令打包一个文件夹下的所有文件,上面有介绍说打包所有的文件,后面跟的是“*”或者“*/.”,我试了是,结果:
从上面我发现,“*”可以成功打包,“*/.”不可以成功打包。后来灵机一闪,尝试了先“.”:
从而证明我的猜想是对的,能够打包全部文件的是“*”或“.”,而“*/.”不成功可能是文章作者写错了。而视频中为什么能够打印,我理解不了。只能强行解释了,“*.*”代表了文件名.文件类型的所有文件,如果没有则就不能打包,故而我有进行了尝试,因为前面生成了test.jar文件,那么用“*.*”应该可以进行再次打包:
事实证明,确实这样。“*”或“.”代表了当前目录中的所有文件及文件夹,而"*.*"只是所有文件,而不包括文件夹。
使用Jar文件
仅仅生成Jar文件就可以了吗?NO,NO,NO!其它类中你总得说明怎么用Jar文件吧:首先需要将Jar文件存放在classpath环境配置中,就如同前面我有提到的jar文件的环境配置,这里就是其需要的地方:
那么该怎么具体使用呢?不需要怎么处理了,只要程序写的没问题,就可以直接编译了:
结果是编译和运行都正确。所以Jar文件有很大的利!Jar一般使用来讲class文件进行包装的,这样只要拿来Jar文件谁都可以使用Jar文件中的类(class)。
同样,需要注意一点:classpath环境是从前向后查找class文件的,如果当前目录里或者Jar文件前的配置路径存在相同的类,则就会出现调用错类或者无法找到对应类(即编译错误)。