课外天地 李树青学习天地Java程序语言课件 → 课件13下载——Java的包


  共有15340人关注过本帖树形打印复制链接

主题:课件13下载——Java的包

帅哥哟,离线,有人找我吗?
admin
  1楼 博客 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信 管理员
等级:管理员 帖子:1940 积分:26616 威望:0 精华:34 注册:2003/12/30 16:34:32
课件13下载——Java的包  发帖心情 Post By:2006/2/26 21:41:18 [只看该作者]

利用Java的包可以更加有效的对类进行管理。

1、简介
一般而言,Java程序文件在编译后,默认总是在当前目录生成字节码文件,同样,如果Java程序文件要调用其他自定义类生成对象,也总是在当前目录中寻找这些类(系统类除外)。这就说明,当前目录是一个Java类的默认容器,可以存放所有Java程序的自定义类,这个默认容器通常也被称为“包”。

2、包的使用
2、1 包的定义
要想改变Java类默认的所在包,可以通过package语句显式的定义包,如:
package myJava;

public class cls
{
        private int val=0;
        
        public void setVal(int v)
        {
                this.val=v;
        }
        
        public int getVal()
        {
                return val;
        }
}

注意:编译含有包的文件需要写入正确的语法,如:
javac -d . cls.java
其中,-d表示javac程序的命令行参数,意思是指将所生成的包放于指定目录中,“.”表示当前目录。

编译后,就会发现在当前目录下生成一个名称为myJava的目录,而生成的字节码文件位于其中。

如果想把包文件放入其他目录,可以用-d参数来定义,如:
javac -d d:\ cls.java


包的结构有时也可以嵌套较多,如:
package myJava.exec;

public class cls
{
        private int val=0;
        
        public void setVal(int v)
        {
                this.val=v;
        }
        
        public int getVal()
        {
                return val;
        }
}
编译后,就会发现在当前目录下生成一个名称为myJava的目录,里面还有个名称为exec的目录,而生成的字节码文件位于其中。

说明:package语句是Java语言中的定义包的基本语句,它的层次是通过目录的形式来表达的,通过这种方式,人们就可以将自定义类放入一个指定的包下。

2、2 包的导入
要想使用一个不位于当前默认包下的类文件,就需要在使用前将类文件的所在包导入,如:
import myJava.exec.cls;

public class exec
{
        public static void main(String args[])
        {
                cls c=new cls();
                
                System.out.println(c.getVal());
        }
}

编译、执行方法与处理一般程序文件无异,为:
javac exec.java
java exec

说明:类前面的包名称能够指引Java找到这个类,但是它也只是在当前路径下查找,如果包不在当前路径下,就需要通过另外一个javac程序的参数-classpath来指定包所在的物理路径,如编译方法:
javac -classpath d:\ exec.java

运行方法稍有不同
如书写:java exec,报错为:NoClassDefFoundError: myJava/exec/cls,说明运行时仍然需要找到包,仍然需要指定包的物理路径。
如书写:java -classpath d:\ exec,报错为:NoClassDefFoundError: exec,说明它无法找到当前程序,因为-classpath已经被完全设置为非当前路径,所以正确的写法是也要将包含当前程序的路径(即当前路径)加上,如:
java -classpath d:\;. exec
注意:两个路径通过“;”分割。


也可以在使用类的同时,直接指定类的所在包,如:
public class exec
{
        public static void main(String args[])
        {
                myJava.exec.cls c=new myJava.exec.cls();
                
                System.out.println(c.getVal());
        }
}

说明:如果将生成的类包放入一个特殊目录,即可不用指定classpath即可编译和运行,这个目录为<JSDK>\jre\classes(可能开始没有被创建,新建之即可)
步骤为:
1)javac -d .  cls.java
2)将包目录拷贝至<JSDK>\jre\classes
3)javac exec.java
4)java exec

注意:如果这一步存在问题,请检查path路径是否正确(最好只是设置为当前J2SDK的工作目录,即<JSDK>\bin,以防止其他JVM的干扰),或者检查classpath的设置(确认是否为.,以防止其他路径下的类产生干扰)

2、3 多个包的导入
反复使用import语句就能够将更多不同包中的类导入当前程序,如:
一个类:
package myJava.exec;

public class cls
{
        private int val=0;
        
        public void setVal(int v)
        {
                this.val=v;
        }
        
        public int getVal()
        {
                return val;
        }
}

另外一个类:
package exec;

public class othercls
{
        private int val=1;
        
        public void setVal(int v)
        {
                this.val=v;
        }
        
        public int getVal()
        {
                return val;
        }
}

使用上述两个类的程序为:
import myJava.exec.cls;
import exec.othercls;

public class exec
{
        public static void main(String args[])
        {
                cls c=new cls();
                System.out.println(c.getVal());
                
                othercls oc=new othercls();
                System.out.println(oc.getVal());
        }
}

输出为:
0
1

但是有时也会出现问题,如:
一个类:
package myJava.exec;

public class cls
{
        private int val=0;
        
        public void setVal(int v)
        {
                this.val=v;
        }
        
        public int getVal()
        {
                return val;
        }
}

另一个类:
package other;

public class cls
{
        private int val=1;
        
        public void setVal(int v)
        {
                this.val=v;
        }
        
        public int getVal()
        {
                return val;
        }
}

使用上述两个类的程序为:
import myJava.exec.cls;
import other.cls;

public class exec
{
        public static void main(String args[])
        {
                cls c=new cls();
                System.out.println(c.getVal());
        }
}

编译报错为:myJava.exec.cls is already defined in a single-type import,意思是说cls这个类已经在myJava.exec包中导入过了,不能再次从other包中导入同名类。其实纵然可以同时导入,程序内部的cls类又会是哪个包中的cls类呢?显然,对于不同包中的同名类不能这样使用。不过,可以采用在类前加上包前缀的方法来实现预期目的,如:
public class exec
{
        public static void main(String args[])
        {
                myJava.exec.cls c1=new myJava.exec.cls();
                System.out.println(c1.getVal());
                
                other.cls c2=new other.cls();
                System.out.println(c2.getVal());                
        }
}

此时,可以看出Java使用包来管理类是具有很多优势的,如
1)首先,对于类文件来说,可以通过包进行更加有效的分类管理,避免将许多类放入同一个目录所带来的混乱。
2)其次,如果一个程序需要使用外部的多个同名类,也可以通过不同的包来限定具体的类。当然,此时的包名称不能再重复了。事实上,一般对于包的起名往往采用本地主机网络域名逆写的方式来表达,如:
package cn.edu.njue;
由于本地主机的网络域名具有唯一性,所以不同编程者生产的类一般不会具有同名包。

考虑下面的情况:
类文件:
package myJava.exec;

public class cls
{
        private int val=0;
        
        public void setVal(int v)
        {
                this.val=v;
        }
        
        public int getVal()
        {
                return val;
        }
}

使用该类的文件:
package cn.edu.njue;

public class exec
{
        public static void main(String args[])
        {
                myJava.exec.cls c1=new myJava.exec.cls();
                System.out.println(c1.getVal());                
        }
}

编译完上述两个类后,会发现当前目录下存在两个目录,没有字节码文件,那么如何运行exec类呢?
直接进入exec所在路径不是办法,因为那样将无法获取cls类。运行exec的正确做法为:
还在当前路径下,指令为:
java cn.edu.njue.exec

2、4 特殊的包形式——jar文件
包除了展示为目录结果以外,它也可以使用文件的形式来展示,这种文件为jar文件(Java Archive File)。它是压缩文件(ZIP格式,可以使用WINRAR或者WINZIP打开),里面既含有目录结构,也含有相关字节码文件。

如下例:
类文件为:
package mypack;

public class cls
{
        public int val=0;
}

使用该类的文件为:
import mypack.cls;

public class exec
{
        public static void main(String args[])
        {
                cls c1=new cls();
                System.out.println(c1.val);            
        }
}

制作方法为:
1)首先,对于上述程序,先将cls类生成字节码文件,指令为:javac -d . cls.java
2)其次,将上述包和字节码文件打包为jar文件,指令为:jar cvf mypack.jar mypack/*.class
屏幕输出为:
标明清单(manifest)
增加:myJava/exec/cls.class(读入= 351) (写出= 251)(压缩了 28%)

观察当前目录,会发现一个jar文件,用解压缩软件打开看看,会发现里面有目录结构和字节码文件,同时还有个系统使用的清单文件。
3)对于生成的jar文件,可以将其放入<JSDK>\jre\lib\ext下,这时就可以直接编译使用该包的其他文件,Java会自动调用,如:
javac exec.java
java exec

注意:如果这一步存在问题,请检查path路径是否正确(最好只是设置为当前J2SDK的工作目录,即<JSDK>\bin,以防止其他JVM的干扰),或者检查classpath的设置(确认是否为.,以防止其他路径下的类产生干扰)

3 friendly类型
一个例子:
类文件为:
public class cls
{
        int val=0; //attention!
}

使用该类的文件为:
public class exec
{
        public static void main(String args[])
        {
                cls c1=new cls();
                System.out.println(c1.val);            
        }
}

输出为:
0

再看一个例子:
类文件为:
package myJava.exec;

public class cls
{
        int val=0;
}

使用该类的文件为:
import myJava.exec.cls;

public class exec
{
        public static void main(String args[])
        {
                cls c1=new cls();
                System.out.println(c1.val);            
        }
}
编译报错为: val is not public in myJava.exec.cls; cannot be accessed from outside package

说明:在Java文件中,如果没有在类成员前加上访问修饰符,默认为friendly类型,这种类型修饰的成员只能由同一个包中的其他类直接访问,而不在同一个包中的其他类就不能直接访问。显然,上例中exec和cls是在两个不同的包中。

注意:这种访问修饰符无需显式写入,默认即为。

4)Java的系统包
Java系统提供的系统类库文件皆位于指定的某个包,这些包全部压缩成了一个jar文件,为<JSDK>\jre\lib\rt.jar文件(可以打开看看,全部都是位于不同包的字节码文件)。原始的类库源代码放在<JSDK>\src.zip文件中(可以打开看看,全部都是源代码文件,值得好好学习)。

一般而言,若要使用这些包中的类也要显式的导入,但是对于lang包中的内容无需显式导入也可以使用,因为该包中包含的类是Java编程语言设计的基础,所以系统自动导入。

其中比较重要的类包括:Object(类体系结构的根)、Class(封装对象或接口运行时的状态)、封装类(封装基本数据类型,为基本数据类型建立对象表达式)、Void类(有一个TYPE域,该域保存对类型void的Class对象的引用)、Math类(提供一些常用的数学运算的方法)、String和StringBuffer(提供常用的字符串运算)以及提供“系统操作”的类(如ClassLoader、Process、Runtime、SecurityManager、System等,功能为管理类的动态加载、外部进程的创建、主机环境查询及安全策略的执行等)。

其他的一些常见包及其功能为:java.io(这个包由对您的输入/输出操作有用的类组成)、java.applet(该包由您在浏览器中执行一个applet所需要的类组成)、java.awt(该包对创建GUI应用程序有用)、java.util(该包提供了许多创建如lists, calendar, date等所需要的类和接口)、java.net(该包提供了许多进行TCP/IP网络编程的类和接口)等。


 

[此贴子已经被作者于2010-12-12 07:41:58编辑过]

 回到顶部