`

完全掌握java中的"包"机制

 
阅读更多

正文

"包"机制是java中特有的,也是java中最基础的知识。一些初学java的朋友,通常象学其它语言一样从教材上copy一些程序来运行,可是却常常遇到莫名其妙的错误提示。这些问题事实上都出在对"包"的原理不够清楚。本文将就此问题进行深入阐述。

一、为什么java中要有"包"的概念?

以一言概之,java中"包"的引入的主要原因是java本身跨平台特性的需求。因为java中的所有的资源也是以文件方式组织,这其中主要包含大量的类文件需要组织管理。java中同样采用了目录树形结构。虽然各种常见操作系统平台对文件的管理都是以目录树的形式的组织,但是它们对目录的分隔表达方式不同,为了区别于各种平台,java中采用了"."来分隔目录。

二、java中包结构和平台的衔接

java中的资源存在于不同平台下时必然会有很大差异。因此跨平台的java包结构和平台之间必须通过一种方式来衔接到一起。事实上它们就是通过我们很熟悉的classpath的设置来衔接到一起的。举个例子:

我在Windows2000环境下的classpath设置如下:

classpath = d:/jdk1.4.2/lib/dt.jar; d:/cjm 

类的衔接关系可以用下图来表达:

从图中可以看出,java中的类的组织是"悬空"的,这样的话,它们可以随意放在任意平台下,但是要在该平台下正确找到一个类,则必须使用classpath来设置类所在目录的前面一部分(即区别于平台的部分)。在java中常常把一棵类树压缩成一个.jar文件,如图中的rt.jar,这并不影响对类的查找,在指定环境变量时可以指定.jar文件所在目录,也可以具体指明.jar的完全查找路径,即上例中的classpath中也可描述成:

classpath = d:/jdk1.4.2/lib; d:/cjm

当正确设置了平台下的classpath环境变量时,java跨平台的特性就体现出来了。即你在编写程序中,描述一个类时,就不用具体指明它的完整路径,而是仅仅指明java中的类路径就可以了,即指出图1中竖线右边的查找路径就可以了。这样的话,你编写的程序拿到任何平台下时,只需要根据类文件的存放目录来书写相应的classpath环境变量,而不用因为类的存放环境变化而修改程序。

注意:java中对于某个类的查找是把classpath中的每一项逐一连接,当一个连接能够正确找到相关类后,便不再向后查找。

三、正确使用"包"

在使用包的过程中有很多需要注意的小细节,这里把常见的问题都列举如下:

1、对类路径的设置通常有两种方法:

i)在系统的环境变量中设置,设置方法依据平台而变;

ii)以命令参数的形式来设置。

如:javac -classpath d:/jdk1.4.2/lib d:/cjm/edu/test/TestFile.java java -classpath .;d:/jdk1.4.2/lib; d:/cjm edu.test.TestFile 

注意:i)javac和java命令有很大区别,可以这样区分,javac是一个平台命令,它对具体的平台文件进行操作,要指明被编译的文件路径。而java是一个虚拟机命令,它对类操作,即对类的描述要用点分的描述形式,并且不能加扩展名,还要注意类名的大小写。

ii)有一个很奇怪的问题,即javac命令后面的classpath默认包含当前目录(符合windows的习惯),可是在java命令后面的classpath却不包含当前目录,所以在它的classpath中一定不能忘了加上当前目录的描述,即加上"."。

2、在java程序中对类路径的描述用"."分隔,而且也有当前目录的概念。如要运行图1中的TestFile必须指明为 edu.test.TestFile。但是如果在类TestFile中要调用和它在同一目录中的TestString,则不必指明目录前缀。

3、在java程序中所有使用到的类都应该清楚的指明这个类的查找路径。一般有两种方法指明:

i)在程序的开始使用import关键字指明。如类TestFile中要用到FileInputStream类,则在程序头中加入import java.io.FileReader; 或import java.io.*;

ii)在程序中用到FileFileReader类处直接写完整路径,如: java.io.FileFileReader fin = new java.io.FileReader("filename");

注意:java.lang包总是被默认导入的。

4、类的目录结构一定要和类中第一句"包声明"一致。如类TestFile.class对应的.java文件的第一句必须包含:package edu.test;

确保类的存放路径和类中指明的"包路径"一致的方法一般有两种:

i)编写.java文件时存放的目录事先确定好,如TestFile.java就直接放在edu/test目录下,然后用下面的语句编译:

javac -classpath d:/jdk1.4.2/lib d:/cjm/edu/test/TestFile.java 

当编译完成后,产生的TestFile.class文件会出现在编译命令中java文件的描述路径中。即出现在d:/test/edu/test中

ii)通过-d参数的使用来编译程序。如使用下面的语句来编译:

javac -d d:/cjm d:/temp/TestFile.java

将在-d后指定的目录d:/cjm下面自动按照packagek中指定的目录结构来创建目录,并且将产生的.class文件放在这个新建的目录下,即在d:/cjm下面建立/edu/test目录,然后产生的TestFile.class放在d:/cjm/edu/test目录下。

5、为了便于工程发布,可以将自己的类树打成.jar文件。如将图1中的edu下面的所有类文件打成一个.jar文件,可以先转到d:/cjm目录,再用下面的命令:

   jar -cvf test.jar edu/

这时会在d:/test下产生一个test.jar文件,此.jar文件中包含edu/下的完整目录结构和文件。使用这个.jar文件时,只需在classpath中指明.jar文件的存放路径即可。

6、对其它资源的使用,如图标文件,文本等资源文件的使用必须要注意,查找资源文件不应从类文件所在的目录开始,而是应该从package指定的类路径的起点开始(图1中从edu所在目录开始)。如图1中看到的文本文件word.txt在resource下面,而类文件TestFile.class在edu/test下,在TestFile.class中要使用到resource中的word.txt,要按如下操作:

fin= new FileReader("resource/word.txt"); 而不应该是:fin= new FileReader("../../resource/word.txt"); 

四、举例

本例用于统计一个文本文件中的单词数,注释中的编号对应前一节的编号:

//TestFile.java package edu.test;//--------------------------------------- 4 import java.io.FileReader;//------------------------------ 3 import java.io.LineNumberReader; class TestFile{ public static void main(String []argv){ TestString ts = new TestString();//---------------- 2 FileReader fin; LineNumberReader line = null; int wordNum = 0; try{ fin= new FileReader("resource/word.txt");//---- 6 line = new LineNumberReader(fin); }catch(Exception e){ e.printStackTrace(); System.exit(0); } while(true){ try{ String temp = line.readLine(); wordNum += ts.CountWord(temp); }catch(Exception e){ break; } } try{ line.close(); }catch(Exception e){}; System.out.println("Word count is:" + wordNum); } }

//TestString.java package edu.test; import java.util.*; class TestString { int CountWord(String str){ StringTokenizer token = new StringTokenizer(str); return token.countTokens(); } }

两个.java文件存放在d:/temp目录下,当前目录为d:/temp使用下面的命令进行编译:

d:/temp>javac -classpath d:/jdk1.4.2/lib -d d:/test *.java

用下面的命令运行:

//--------------------------------- 1 d:/temp> java -classpath .;d:/jdk1.4.2/lib; d:/test/com edu.test.TestFile 

如果需要打包的话,先转到d:/test,然后用下面命令:

//--------------------------------- 5 jar -cvf test.jar edu/ 

这时可产生一个test.jar文件,可将此文件置于任何平台下使用。

分享到:
评论

相关推荐

    完全掌握java中的包机制

    完全掌握java中的包机制 完全掌握java中的包机制

    完全掌握java包机制

    java的包机制介绍和使用方法,全面,简单易懂

    java+毕业设计+扫雷(程序)

    2. 掌握Java事件处理机制,如按钮点击事件和键盘事件。 3. 练习Java数据结构,如数组和链表,以及它们的应用。 其他说明: 本教程以实际操作为主,通过详细步骤和代码示例,帮助读者逐步构建和测试扫雷游戏。教程中...

    Java核心技术 卷Ⅰ:基础知识 【中文】(第八版)

    掌握接 口的使用将可以获得Java完全的面向对象程序设计的能力。本章还将介绍Java的一个有用的技 术特性—内部类。内部类可以使代码更清晰、更简洁。 第7章开始细致地讨论应用程序设计。每一个Java程序员都应该了解...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    第8章 Java中的包(Package)命名习惯和注释 193 教学视频:43分钟 8.1 Java中的包(Package) 193 8.1.1 Java中的包 193 8.1.2 在Eclipse中使用包 194 8.1.3 天上掉下个package 197 8.1.4 包带来了什么? 197...

    实验九 图形用户界面GUI(文档中包含可执行源码)

    4.重点掌握Java的事件管理机制。 2、相关知识点 Java Swing是Java基础类(JFC)的一部分,用于创建基于窗口的应用程序。它建立在AWT(抽象窗口工具包)API的顶部,并且完全用Java编写。 与AWT不同,Java Swing提供了...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    第8章 Java中的包(Package)命名习惯和注释 193 教学视频:43分钟 8.1 Java中的包(Package) 193 8.1.1 Java中的包 193 8.1.2 在Eclipse中使用包 194 8.1.3 天上掉下个package 197 8.1.4 包带来了什么? 197...

    疯狂JAVA讲义

    学生提问:构造器是创建Java对象的途径,是不是说构造器完全负责创建Java对象? 141 5.5.2 构造器的重载 142 学生提问:为什么要用this来调用另一个重载的构造器?我把另一个构造器里的代码复制、粘贴到这个构造器...

    Java学习笔记

    JAVA吸收C和C++的优点,基础语法与C语言模式完全一样,容易掌握 JAVA健壮性高,它去掉指针、内存申请和释放、无条件转移语句,但有引用的概念,实际传递的是内存地址 (大小为4字节) JAVA提供多线程、提供动态下载...

    JAVA面试题最全集

    9.Java中访问数据库的步骤,Statement和PreparedStatement之间的区别。 10.找出下列代码可能存在的错误,并说明原因: 二、JSP&Servlet技术 1.描述JSP和Servlet的区别、共同点、各自应用的范围 2.在Web开发中...

    Java毕业设计-JAVA泡泡堂网络游戏的设计与实现(源代码+论文).rar

    **JAVA泡泡堂网络游戏的设计与实现(源代码+论文)** 本资源提供了一个基于Java语言开发的泡泡堂网络游戏的设计与...通过学习和实践,可以掌握Java网络游戏开发的基本技术和方法,为进一步的开发和创新打下坚实基础。

    ElasticSearch5.2全网最全技术视频

    (6)课程学完之后,学员可以掌握es所有核心知识点,理解es核心原理,而且能够熟练动手操作所有学到的知识和功能,并且能够掌握ES集群的基本部署,并且基于Java开发一个适用于中小型企业的搜索引擎以及数据分析系统...

    C#微软培训资料

    14.1 C#的继承机制.155 <<page 3>> page begin==================== 14.2 多 态 性 .159 14.3 抽象与密封 .163 14.4 继承中关于属性的一些问题.169 14.5 小 结 .172 第四部分 深入了解 C#.174 第十...

    asp.net知识库

    利用委托机制处理.NET中的异常 与正则表达式相关的几个小工具 你真的了解.NET中的String吗? .NET中的方法及其调用(一) 如何判断ArrayList,Hashtable,SortedList 这类对象是否相等 帮助解决网页和JS文件中的中文...

    windows 程序设计

    Windows包括一个机制,能够在执行时连结使用动态链接库中例程的程序。Windows自身基本上就是一个动态链接库的集合。 Windows是一个图形接口,Windows程序能够在视讯显示器和打印机上充分利用图形和格式化文字。图形...

    Beetl模板引擎-其他

    2、非常简单:类似Javascript语法和习俗,只要半小时就能通过半学半猜完全掌握用法。拒绝其他模板引擎那种非人性化的语法和习俗。3、超高的性能:Beetl 远超过主流java模板引擎性能,如5-6倍于freemarker,2倍于传统...

Global site tag (gtag.js) - Google Analytics