目录
在上一节中我们写了一个Hello World程序。其中有一个Hello类。Hello World程序是每个教学的第一个程序,有许许多多的人都写过不同版本,但是他的类名也为Hello。这样如果两个Hello world类放到了一起,那就会产生命名冲突。那如何解决这个问题呢?在C/C++中有命名空间。java提供一个包来处理这个问题。
package是java的关键字,用来定义包的。它的格式是:
package 包名称.子包名称;
在上篇文章中的代码中加入一句:
package com.kanglin; //声明包 public class Hello { public static void main(String args[]) { System.out.println("Hello World!"); } }
编译:
k@k-C410:/data/test$ javac Hello.java
生成中间代码: Hello.class
查看中间代码:
k@k-C410:/data/test$ javap -sysinfo Hello.class
Classfile /data/test/Hello.class
Last modified Nov 17, 2013; size 428 bytes
MD5 checksum 9f0fea0f1cabbc4a4960a4e07478752b
Compiled from "Hello.java"
public class com.kanglin.Hello {
public com.kanglin.Hello();
public static void main(java.lang.String[]);
}
发现类命名与前面的不同了,这里为:com.kanglin.Hello,前面就是Hello
执行:
k@k-C410:/data/test$ java com.kanglin.Hello
Error: Could not find or load main class com.kanglin.Hello
出现错误提示,找不到类。
这是因为com.kanglin.Hello表示在com/kanglin目录中找Hello类。而我们编译出来的中间文件Hello.class并不在这个目录下。
正确的编译方法:
编译:
k@k-C410:/data/test$ javac -d . Hello.java
参数-d:表示在哪个目录下产生类文件
k@k-C410:/data/test$ ls
com Hello.java
k@k-C410:/data/test$ cd com/kanglin
k@k-C410:/data/test/com/kanglin$ ls
Hello.class
你可以看到类文件产生到了指定的目录下。
我们再看下类文件的信息:
k@k-C410:/data/test/com/kanglin$ javap -sysinfo Hello.class
Classfile /data/test/com/kanglin/Hello.class
Last modified Nov 17, 2013; size 428 bytes
MD5 checksum 9f0fea0f1cabbc4a4960a4e07478752b
Compiled from "Hello.java"
public class com.kanglin.Hello {
public com.kanglin.Hello();
public static void main(java.lang.String[]);
}
从信息中看出,与没加-d参数产生的类文件是一样的。
从上面可以看出,由于加了-d参数,编译工具自动生成了文件夹(包)。
运行:
k@k-C410:/data/test$ java com.kanglin.Hello
Hello World!
注意:在上面的整个操作过程中注意目录的变化。
包的引用:
上面示例了如何做一个包,那么如何引用已做好的包呢?
这需要关键字:import
import 包名称.子包名称.类名称 //手工导入所需要的类
import 包名称.子包名称.* //由jvm导入所需要的类
package com.kanglin; //这个必须在第一行 import java.util.logging.*; //导入java的日志包 public class Hello { public static void main(String args[]) { //System.out.println("Hello World!"); Logger logger = Logger.getLogger("com.kanglin"); logger.log(Level.WARNING, "Hello World!"); } }
java日志包的详细信息见:http://docs.oracle.com/javase/6/docs/technotes/guides/logging/overview.html
编译:
k@k-C410:/data/test$ javac -d . Hello.java
k@k-C410:/data/test$ ls
com Hello.java
运行:
k@k-C410:/data/test$ java com.kanglin.Hello
Nov 17, 2013 3:36:42 PM com.kanglin.Hello main
WARNING: Hello World!
打包:
一般一个库会包含许多类,当写完后,会有许多目录和类文件,这样不便第三方使用,所以会把这个目录和文件打包成一个包。这需要jar命令:
jar命令中主要有下列三个参数:
-c 创建新的归档文件
-v 在标准输出中生成详细输出
-f 指定归档文件名
把我们的Hello World打包:
k@k-C410:/data/test$ ls
com Hello.java
k@k-C410:/data/test$ jar cvf kanglin.jar com
已添加清单
正在添加: com/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: com/kanglin/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: com/kanglin/Hello.class(输入 = 568) (输出 = 343)(压缩了 39%)
k@k-C410:/data/test$ ls
com Hello.java kanglin.jar
在当前目录下生成了kanglin.jar文件。
查看kanglin.jar的内容:
k@k-C410:/data/test$ jar -tvf kanglin.jar
0 Sun Nov 17 15:48:30 CST 2013 META-INF/
68 Sun Nov 17 15:48:30 CST 2013 META-INF/MANIFEST.MF
0 Sun Nov 17 15:36:08 CST 2013 com/
0 Sun Nov 17 15:36:08 CST 2013 com/kanglin/
568 Sun Nov 17 15:36:08 CST 2013 com/kanglin/Hello.class
你会发现多出了一个META-INF目录和MANIFEST.MF文件,这个就是这个包的清单文件。jar本质就是一个zip的压缩包,
包使用:
jar使用,删掉com目录
k@k-C410:/data/test$ ls
Hello.java kanglin.jar
k@k-C410:/data/test$ java -classpath kanglin.jar com.kanglin.Hello
十一月 17, 2013 3:56:12 下午 com.kanglin.Hello main
WARNING: Hello World!
java工具会自动从参数-classpath中指定的包或目录中查找类,然后再加载执行。
加上参数:-verbose,你可以更清楚地看清加载过程
k@k-C410:/data/test$ java -verbose -classpath kanglin.jar com.kanglin.Hello
总结: