---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

黑马程序员-------------(三)异常机制和包机制

目录

一 异常类

    1.异常

    2.异常的处理

    3.异常类的方法

    4.自定义异常

    5.异常注意事项

二 包

    1.包的概念

    2.package 关键字和 protected 关键字

    3.import 关键字

三 Jar包

注:本章重点内容:异常体系,RuntimeException。对于重点内容,根据知识的重要程度用◆◆◆、◆◆◆◆、◆◆◆◆◆进行了标注。

####################################################################################
一 异常类 Exception
####################################################################################

1.异常

分类:
(1)编译时异常(编译时被检测)。在编译时,如果没有处理(没有throws也没有try),编译失败;该异常被标识,代表者可以被处理。
(2)运行时异常(编译时不检测)。在编译时,不需要处理,编译器不检查;该异常的发生,建议不处理,让程序停止。需要对代码进行修正。
好处:
(1)将问题进行封装。
(2)将正常流程代码和问题处理代码相分离,方便于阅读。
特点:异常体系中的所有类以及建立的对象都具备可抛性。也就是说可以被throw和throws关键字所操作。只有异常体系具备这个特点。

2.异常的处理

2.1 处理过程:
try中检测到异常会将异常对象传递给catch,catch捕获到异常进行处理。finally里通常用来关闭资源。比如:数据库资源,IO资源等。

2.2 异常处理语句格式:

(1)格式一
    try
    {
        需要被检测的代码;
    }
    catch (异常类 变量)
    {
        处理异常的代码;
    }

(2)格式二
    try
    {
        需要被检测的代码;
    }
    finally
    {
        一定会执行的代码;
    }

(3)格式三
    try
    {
        需要被检测的代码;
    }
    catch (异常类 变量)
    {
        处理异常的代码;
    }
    finally
    {
        一定会执行的代码;
    }

注意:
a.try是一个独立的代码块,在其中定义的变量只在该变量块中有效。如果想在try以外继续使用,需要在try建立引用。在try对其进行初始化。
b.finally中定义的通常是关闭资源代码。因为资源必须释放。
c.finally只有一种情况不会执行。当执行到System.exit(0);fianlly不会执行。
d.catch是用于处理异常。如果没有catch就代表异常没有被处理过,如果该异常是检测时异常。那么必须声明。

2.3 异常的声明
如果函数声明了异常,调用者需要进行处理。处理方法可以throws可以try。
作用:提高安全性,让调用者进行处理。不处理编译失败。

throw和throws的区别:
(1)定义
throws用于标识函数暴露出的异常。throw用于抛出异常对象。
(2)区别
throws定义在函数上,用于抛出异常类,可以抛出多个,用逗号隔开;throw定义在函数内,用于抛出异常对象。
(3)应用
定义功能方法时,需要把出现的问题暴露出来让调用者去处理。那么就通过throws在函数上标识;
在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。

注意:
当函数内有throw抛出异常对象,并未进行try处理时。必须要在函数上声明,否则编译失败(但如果抛出的是运行时异常,函数上可以不用声明)。

2.4 对多异常的处理。
(1)声明异常时,建议声明更为具体的异常。这样处理的可以更具体。
(2)声明几个异常,就对应有几个catch块。不要定义多余的catch块。如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。

◆◆◆【2.5 RuntimeException】◆◆◆
Exception 中有一个特殊的子类异常 RuntimeException 运行时异常。如果在函数内抛出该异常,函数上可以不用声明,编译一样通过;如果在
函数上声明了该异常。调用者可以不用进行处理。编译一样通过。不用在函数声明,是因为不需要让调用者处理。当该异常发生,希望程序停止。
因为在运行时,出现了无法继续运算的情况,希望停止程序后,对代码进行修正。

3.异常类的方法

构造方法摘要
public Exception()
          构造详细消息为 null 的新异常。
public Exception(String message)
          构造带指定详细消息的新异常。
方法摘要
public String getMessage()
          返回此异常的详细消息字符串。 格式:异常信息
public String toString()
          返回此异常的简短描述。       格式:异常名称:异常信息
public void printStackTrace()
          将此异常及其追踪输出至标准错误流,打印异常的堆栈的跟踪信息。格式:异常名称:异常信息 异常出现的位置
public void printStackTrace(PrintStream s)
          将此异常及其追踪输出到指定的输出流。通常用该方法将异常内容保存在日志文件中,以便查阅。

4.自定义异常
因为项目中会出现特有的问题,而这些问题并未被java所描述并封装对象。所以对于这些特有的问题可以按照java的对问题封装的思想。将特有的
问题。进行自定义的异常封装。

4.1 如何定义异常信息呢?
因为父类中已经把异常信息的操作都完成了。所以子类只要在构造时,将异常信息通过super语句传递给父类。那么就可以直接通过getMessage方
法获取自定义的异常信息。

4.2 如何自定义异常
为了让自定义的异常具备可抛性和操作异常的共性方法,定义类继承Exception或者RuntimeException。当要定义自定义异常的信息时,可以使用
父类已经定义好的功能。将异常信息传递给父类的构造函数。

1     class MyException extends Exception
2     {
3         MyException(String message)
4         {
5             super(message);
6         }
7     }


5.异常注意事项

5.1 异常的处理原则:
(1)处理方式有两种:try 或者 throws。
(2)调用到抛出异常的功能时,抛出几个,就处理几个。一个try对应多个catch。
(3)多个catch块时,父类的catch块放到最下面。

5.2 异常的转换
(1)当捕获到的异常,本功能处理不了时,可以继续在catch中抛出。

1     try
2     {
3         throw new AException();
4     }
5     catch (AException e)
6     {
7         throw e;
8     }

 


(2)如果该异常处理不了,但并不属于该功能出现的异常。可以将异常转换后,在抛出和该功能相关的异常。或者异常可以处理,但需要将异常产
    生后和本功能相关的问题提供出去,让调用者知道。并处理。也可以将捕获异常处理后,转换新的异常。比如,汇款的例子。

1     try
2     {
3         throw new AException();
4     }
5     catch (AException e)
6     {
7         // 对AException处理。
8         throw new BException();
9     }


5.3 异常在子父类覆盖中的体现;
(1)子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。
(2)如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
(3)如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。如果子类方法发生了异常。只能try不能抛。

####################################################################################
二 package包
####################################################################################

1.包的概念
(1)java中的包相当于文件系统中的文件夹。
   作用:对类文件进行分类管理;给类提供多层命名空间。
   特点:写在程序文件的第一行。
   格式:类名的全称的是  包名.类名。
(2)多层包目录
  package packa.haha.hehe;
  编译生成的class文件会存在于指定路径下的packa文件夹中的haha文件夹中的hehe文件夹中
注意:
  包也是一种封装形式。

2.package 关键字和 protected 关键字

2.1 package 关键字
package关键字用于定义包,放在程序文件的第一行,因为先有包后有文件。如果源文件带有package这样的关键字定义包的话,在编译时需要加参
数javac -d 路径名(如果是当前目录可以用.表示) java文件名.java。

2.2 包的常见错误提示

1     package pack;
2     class  PackageDemo
3     {
4         public static void main(String[] args)
5         {
6             System.out.println("hello package");
7         }
8     }

 


    javac PackageDemo.java//产生类文件
    java PackageDemo //报错,提示 NoClassDefFoundError 包名错误
    错误原因:类名写错。因为类名的全名是:包名.类名

    java pack.PackageDemo //报错,提示 NoClassDefFoundError PackageDemo找不到
    错误原因:没有pack这个包,需要手动创建或通过dos命令创建

    javac -d . PackageDemo.java //当前路径下产生一个pack文件夹,文件夹内产生类文件
    java pack.PackageDemo//编译通过
    打印结果:"hello package"。

2.3 protected 关键字
protected:保护,权限修饰符。用于包与包之间,protected是为其他包中的子类提供的一种特殊权限。同一个包中protected作用不大,只限于覆盖。即子类中的默认权限无法覆盖该方法,必须是protected或public才可以形成覆盖。

2.4 包与包之间的访问
被访问的包中的类权限必须是public的。类中的成员权限:public或者protected。

2.4.1 四种权限
四种权限         public   protected   default     private
同一个类中          ok         ok          ok           ok
同一个包中          ok         ok          ok                
不同包中子父类    ok         ok                          
不同包中其它类    ok          

2.4.2 总结:
(1)包与包之间进行访问,被访问的包中的类以及类中的成员,需要public修饰。不同包中的类可以通过建立另一个类的对象,调用另一个类中
的公有成员。
(2)不同包中的类可以有继承关系,子类不仅可以访问被public修饰的成员,还可以直接访问父类中被protected权限修饰的成员。
(3)包与包之间可以使用的权限只有两种,public  protected。
(4)如果同一个包中有两个类,想在其它包中对这两个类都建立对象访问,就需要写两个java文件,都保存在该包中。在一个java文件中是无法做到的。因为要想两个类都能被访问,这两个类都要被public修饰,而类名前加public以后,类名必须要和java文件名保持一致,两个公有类,java文件名无法确定。所以一个java源文件里,不能出现两个和两个以上的公有类或者接口。
(5)当一个包中的类调用了另外一个包中的类时,需要先将被调用的包中的类编译后才能编译本类。

2.4.3 包与包之间访问常见错误提示
    
//DemoA.java源文件

 1     package packa;
 2     //class DemoA//错误三
 3     public class DemoA
 4 
 5     {
 6         //void show()//错误四
 7         public void show()
 8         {
 9             System.out.println("DemoA show");
10         }
11     }


//PackageDemo.java源文件

 1     package pack;
 2     class  PackageDemo
 3     {
 4         public static void main(String[] args)
 5         {
 6 
 7             //DemoA a= new DemoA();//错误一
 8             packa.DemoA a= new packa.DemoA();//错误二
 9             a.show();
10         }
11     }

   
    /*
    javac -d d:\myclass DemoA.java
    javac -d d:\myclass PackageDemo.java
    PackageDemo.java:8: 找不到符号
    符号: 类 DemoA
    位置: 类 pack.PackageDemo
                    DemoA a= new DemoA();
                    ^
    PackageDemo.java:8: 找不到符号
    符号: 类 DemoA
    位置: 类 pack.PackageDemo
                    DemoA a= new DemoA();
                                  ^
    2 错误
    */
错误一
    错误原因:类名写错。因为类名的全名是:包名.类名
    
       
    /*
    javac -d d:\myclass DemoA.java
    javac -d d:\myclass PackageDemo.java
    PackageDemo.java:8: 软件包 packa 不存在
                    packa.DemoA a= new packa.DemoA();
                         ^
    PackageDemo.java:8: 软件包 packa 不存在
                    packa.DemoA a= new packa.DemoA();
                                             ^
    2 错误
    */
错误二
    错误原因:packa包不在当前目录下。需要设置classpath,告诉jvm去哪里找指定的packa包。
   
    /*
    set classpath=d:\myclass
    javac -d d:\myclass DemoA.java
    javac -d d:\myclass PackageDemo.java
    PackageDemo.java:8: packa.DemoA 在 packa 中不是公共的;无法从外部软件包中对其进行访问
                    packa.DemoA a= new packa.DemoA();
                         ^
    PackageDemo.java:8: packa.DemoA 在 packa 中不是公共的;无法从外部软件包中对其进行访问
                    packa.DemoA a= new packa.DemoA();
                                             ^
    2 错误
    */
错误三
    错误原因:有了包,范围变大,一个包中的类要被访问,必须要有足够大的权限。所以被访问的类要被public修饰。

    


    /*
    javac -d d:\myclass DemoA.java
    javac -d d:\myclass PackageDemo.java
    PackageDemo.java:9: show() 在 packa.DemoA 中不是公共的;无法从外部软件包中对其进行访问
                    a.show();
                     ^
    1 错误
    */
错误四
    错误原因:类公有后,被访问的成员也要公有才可以被访问。

3.import 关键字

import:导入。导入的是包中的类,不能导入包中的包。
作用:简化类名的书写。导入类后,写代码时,该类的包名可以省略,按原来的写。但是当导入包中的类出现重名时,代码中这个类必须加包名。

注意:
a.一个程序文件中只有一个package,可以有多个import。
b.不要写通配符 * ,需要用到包中的哪个类,就导入哪个类。
c.定义包名不要重复,可以使用url来完成定义,url是唯一的。

####################################################################################
三 Jar包
####################################################################################
Jar包是Java的压缩包。

1.特点:
(1)方便项目的携带;
(2)方便于使用(只要在classpath设置jar路径即可);
(3)数据库驱动(SSH框架等都是以jar包体现的)。

2. jar包的常见命令
通过jar.exe工具对jar的操作。
-c:创建压缩文档。
-f:指定存档名称。
-v:显示详细信息。
-t:列出文档目录。
-x:从档案中提取指定的 (或所有) 文件。
-m:加入自定义清单信息。

3. jar包的常见操作
创建jar包 jar -cvf mypack.jar packa packb//将当前路径下的packa和packb压缩为名称为mypack的jar包。
查看jar包 jar -tvf mypack.jar             //查看当前路径下的mypack.jar文件内容
查看jar包 jar -tvf mypack.jar >d:]1.txt  //将当前路径下的mypack.jar文件内容定向到d盘根目录下的1.txt文件中,如果有同名文件则覆盖
解压缩      jar -xvf mypack.jar             //将jar包解压缩
自定义jar包的清单文件 jar –cvfm  mypack.jar  mf.txt  packa packb

注意:
> 数据重定向

4. jar包和普通压缩包的区别
包的目录变成了jar包    ,让classpath指向该jar包,可以直接运行jar包中的class文件
jar包生成后会自动生成一个文件夹,这个文件夹内存放了一个配置清单文件,文件内数据可以通过改动让jar包有一些特殊意义或特殊操作方式如双击能执行。

5. 使jar包能双击执行
(1)应用:
通常应用于Java制作的图形界面程序。由于它不会在控制台上显示,所以对于一个hello world小程序制作成可双击执行的jar包是没有意义的。
(2)更改jar包中配置清单内容:
在生成jar包前,在包所在路径下建立一个文件(后缀名无所谓,如1.txt),用记事本打开写入Main-Class:空格包名.主函数所在类名回车。如Main-Class: packa.JarDemo。如果不写空格会在打包成jar包时发生IO异常无效的头字段,加空格是把键和值分开。如果没有回车则认为这行数据没有结束,打包成jar包后1.txt文件中的内容没有加载进配置清单。
(3)打包成jar包:
在dos命令行窗口进入package包所在目录,输入jar -cvfm jar包名.jar 自定义文件名 包名(如 jar -cvfm my.jar 1.txt packa)。
(4)验证是否配置成功:
用解压缩软件打开jar包并查看配置清单内容是否增加了Main-Class,如果有了则配置成功。
(5)在本地注册jar文件:
jar文件必须要在本地注册过才能用,安装版的jdk会自动注册,绿色版的需要手动注册。
winXP下注册方法:
窗口工具栏中点击 工具--文件夹选项--文件类型,找到jar类型,点击高级,查看操作中是否有open选项,如果有则可以正常运行。如果都没有工具--文件夹选项--文件类型--新建--在文件扩展名中输入jar--确定--选中新建的jar--高级--更改图标(可选)--新建--操作中输入open--用于执行操作的应用程序框选择浏览--在jdk或jre中的bin目录下一个javaw.exe--打开--在生成的路径后面加上一个参数-jar--确定。

posted @ 2013-07-03 14:55  赵晨光  阅读(352)  评论(0编辑  收藏  举报
---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ------- --------------- 详细请查看:http://edu.csdn.net