Java基础10:异常;包;

来源:互联网 发布:佳能e618清零软件 编辑:程序博客网 时间:2024/05/29 03:23
关键字:异常;包;

一、finally

finally代码块,定义的是一定会被执行的代码,无论是否有异常。通常用于关闭资源,例如数据库。catch中的return意味结束主函数,但finally中的内容仍然会执行

    数据库异常发生后,catch内,可以定义一个特有的数据库异常处理方式;再抛出一个异常给数据接受者,告诉他数据没存成功,让他去处理。也可以抛出数据库异常给接受者,但并不合适,接受者不能处理,也不能打破自己内容的封装性。数据库中的链接一定要关闭,否则占用资源,所以还有加上finally代码块。

    软件开发中的“分层思想”,即模块化的开发,每个人都只处理自己的职责,例如处理数据库和数据。出现问题后,自己处理问题,然后将问题导致的情况暴露出去给其他人,例如,仓库漏水,货物发霉,仓库保管员自己处理漏水问题,将货物发霉的情况告诉取货人即可,原因可说可不说,但没货的情况必须说。这就是问题的封装。

    windows可以创建文件,java通过调用windows的功能来创建文件,使用了windows的资源,无论创建是否成功,都要释放资源。所以只要调用资源,就一定要做关闭资源的动作,用finally。还有就是某些特定的代码一定要执行一下。

   

二、异常语句的格式

    格式一:try{ }catch( ){ }finally{ }

    格式二:try{ }catch( ){ }

    格式三:try{ }finally{ }

    格式四:try{ }catch( ){ } catch( ){ }catch( ){ }

    函数内抛出异常,例如throw new Exception();,函数上一定要标识;如果函数内部自行解决异常,函数上可以不用标识。问题的解决就是,抛出或处理catch。但是catch内部不能抛出,因为又需要在函数上标识,但可以有完整的try、catch语句。try内部也可以有完整的try、catch语句。

    try{ }finally{ }直接编译不能通过,必须在主函数上标识,没有catch就没有处理。针对这种情况:程序运行时可能会调用一些资源,程序运行时出现了问题,处理异常的同时,必须用finally关闭资源,因为处理异常的人可能也不会关闭资源。将一定要执行的内容放在finally中

   

    注意:

    1. catch用于处理异常,如果没有catch就代表异常没有被处理;如果该异常是检测时异常,那么必须声明。

    2. finally用于必须要执行的内容,例如,关闭资源。

 

三、异常在子父类中的覆盖

    1. 子类在赋给父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或该异常的子类。父类已经有了问题,并已经有了解决方式,子类不能超过父类的问题,因为无法解决,所以只能继承父类的问题或问题的子类,也就是早期的程序不能处理后期产生的新异常。

    当子类的异常超过了父类的范围,最终只能在子类内部自行解决,不能抛出。

    2. 如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。

    根本的原则是,子类抛出的异常,父类能够处理

    3. 如果父类或接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。如果子类的方法发生了异常,就必须要在主程序进行try处理,绝对不能抛出,很常见。

    4、如果子类方发发生了异常,就必须要进行try处理,绝对不能抛


    5、如果在子类的覆盖方法确实需要抛出非父类的异常或者该异常的子类,则必须在内部解决

class AException extends Exception{}class BException extends Exception{}class Fu{    void show() throws AException{}}class Zi extends Fu{    void show() throws AException{}  //或者  void show() throws BException{  因为父类已经有问题,不能比父类还有问题}class Demo{    public static void main(String[] args){        ExceptionDemo ed = new ExceptionDemo();        try{            ed.div(1,-1);        }catch(FuShuException e){          System.out.println(e.getMessage());        }finally{            System.out.println("finally");//finall中存放的是一定会被执行的代码        }    }}


四、异常的总结

   1.异常:是对问题的描述,将问题进行对象的封装。

   2. 异常体系:

    Throwable

         |----Error

         |----Exception

               |-----RuntimeException

 

    3.异常体系的特点:异常体系中的所有类以及建立的对象都具备可抛性。也就是可以被throw和throws关键字所操作。只有异常体系具有这个特点。

   

   4. throw 和throws的区别

    throw定义在函数内,用于抛出异常对象。

    throws定义在函数上,用于抛出异常类,可以抛出多个用逗号隔开。

 

    当函数内有throw抛出异常对象时,并未进行try处理,必须在函数上声明,否则编译失败。注意,RuntimeException除外。如果函数内抛出RuntimeException异常,函数上可以不用声明。函数上抛出RuntimeException,可以处理也可不处理。

    如果函数声明了异常,调用者需要进行处理,处理方式可throws可try。

   

    5.异常有两种:

    a. 编译时被检测异常。javac查阅代码,发现异常,该异常在编译时,如果没有处理,编译失败。该异常被标识,代表可以被处理。

    b. 运行时异常(编译时不检测)。编译时不需要处理,编译器不检查。该异常发生,建议不处理,让程序停止,需要对代码进行修正。

 

    6.异常处理的语句

   try{              需要检测的代码;}catch (){       处理异常的代码;}    finally       {              一定会执行的代码;}

    有三种结合格式。

    注意

a. finally中定义的通常是关闭资源代码,因为资源必须要释放。

b. 只有一种情况finally内部语句不执行,catch里有System.exit(0);,系统退出,虚拟机结束。

   

    7.自定义异常

    定义类继承Exception或者RuntimeException,

    a. 为了让该自定义类局部可抛性。

    b. 让该类具备操作异常的共性方法。

    当要定义自定义异常信息时,可以使用父类已经定义好的功能。

    将异常信息传递给父类的构造函数,

    class MyException extends Exception{              MyException(String message)              {                     super(message);              }}


按照java的面向对象的思想,将程序中出现的特有问题进行封装。

 

8.异常的好处

a. 将问题进行封装成对象。

b. 将正常流程代码和问题处理代码相分离,方便阅读。

 

9.异常的处理原则

a. 处理方式有两种,try、catch或者throw。只有catch才算处理。

b. 调用抛出异常的功能时,抛出几个异常就处理几个,不多不少。一个try对应多个catch情况。

c. 多个catch,父类的catch放到最下面。

d. catch内需要定义针对性的处理方式,不要定义printStackTrace或者输出语句,也不要不写。当捕获到的异常,本功能处理不了时,可以继续在catch中抛出。

try{       throw new AException();}catch (AException e){       throw e;}        

如果该异常处理不了,但并不属于该功能出现的异常。可以将该异常转换后,再抛出和该功能相关的异常。

或者异常可以处理,当需要将异常产生的和本功能相关的问题提供出去,让调用者知道,并处理。也可以将捕获异常处理后,转换新的异常。

try{       throw new AException();}catch (AException e){       //对AException进行处理。       throw new BException();}    


异常的注意事项

在子父类覆盖时:

1. 子类抛出的异常必须是父类异常的子类或者子集。

2. 如果父类或者接口没有异常抛出时,子类覆盖出现异常,只能catch处理不能抛出。

 

参考例子:用电脑上课和计算图形面积。

例1:

class Demo{       public static void main(String[] args)       {              try              {                     showExce();                     // throw new Exception();肯定发生异常,下面无法执行。编译错误。                     System.out.println("A");//有异常不执行,没有异常就执行。              }              catch (Exception e)              {                     System.out.println("B");              }       }        public static void showExce() throws Exception       {              throw new Exception();//将异常封装在函数中,函数上声明,有可能出问题。       }}


    注意:throw单独存在时,下面不能有执行语句,无法执行,无论是在主函数还是在一般函数,出现编译错误。形式和return、contiune、break一样。

 

    例2:

    try内部也可以有完整的try、catch语句,内部的语句是否处理无所谓。

   

 class Demo{       public static void fun()       {              try              {                     throw new Exception();                     //System.out.println("A");              }              catch (Exception e)              {                     System.out.println("B");              }       }       public static void main(String[] args)       {              try              {                     fun();              }              catch (Exception e)              {                     System.out.println("C");              }       }}

   

五、包(package)

    对类文件进行分类管理。在一个文件夹中,会有内容不同但类名相同的类文件,例如,2个demo.class文件,后面的类文件会覆盖前面的类文件,造成丢失数据。可以将同名的类文件放入不同的文件夹进行管理,这些文件夹就是“包”。

   

    给类提供多层命名空间。例如,将2个Demo.class文件放入A、B两个文件夹内,调用某个文件夹下的文件,例如A的Demo.class文件,不会发生混淆。

 

    写在程序文件的第一行。定义包名,所有字母小写。例如,package pack;

 

    类名的全称是:包名.类名。有了包名后,类名发生了变化,运行时按照包名.类名执行。同时,在相应位置建立文件夹,将类文件放入文件夹中,源文件可以不管。

也可以通过在编译时,设定路径将类文件放入指定的文件夹内,例如,javac –d . PackageDemo.java,编译时将Package.class文件放入当前目录下的pack文件夹内;系统自动生成pack文件夹,也可以将其指定在其他文件,例如:javac –d d:\myclass PackageDemo.java。如果想设定classpath更快的找到包,只要设定路径为包的父目录即可,因为类文件和包是一个整体。如果不写包,java会将当前文件夹作为默认包存在。

    包的出现让java的源文件和类文件相分离,保护了源文件。最好将类文件单独存放,不要混在一起。

  

    利用包调用类的过程中的可能错误

    1. 类名写错。一旦类文件进入包,类名的全名改为:包名.类名,包与类文件构成一个整体。代码要变现出来,运行时也要表现出来。

    2. 包不在当期目录下。需要设置classpath,告诉虚拟机去哪里找包。

    3. 类的权限不够大。有了包,范围变大后,涉及到权限问题。一个包中的类要被其他包中的类访问,必须要有足够大的权限。外部类的权限修饰符只有2个:public和默认。

4. 函数的权限不够大。类公有后,被访问的成员也要公有,才可以被访问。函数的权限有3:public、private和默认。类和函数都必须要公有。

 

    包也是一种封装。开发中,先写包再写类。有的类可以对外提供,有的只供内部使用。所以,不能说封装只是私有,私有只是其中一种。只要没有public就算封装。

 

    总结:

    1. 包与包之间进行访问,被访问的包中的类以及类中的成员,都需要public修饰。

    2. 不同包的类之间仍然可以继承,只要是类之间就可以继承。

    3.包与包之间可以使用的权限只有2种:public 和protected。

 

    访问权限总结:    

 

public      

protected

默认 

private

同一个类中

同一个包中

 

 

 

子类

 

 

 

 

不同包中

 

 

 


   

    protected权限

    不同包的类之间可以直接调用其他类的函数,无论是否继承,只要public即可;不同包中的子类可以直接访问父类中被protected权限修饰的成员,其他类无法调用。创建对象可以。同一个包中,子父类之间,子类覆盖父类protected修饰的成员,只要权限大于或等于即可。

    一个源文件中不能有2个以上的公有类或者接口,如果想在一个包中建立多个类,可以创建多个源文件。

    包里面还可以有包,多个层次,例如,package pack.haha.hehe;:pack包中有haha包,haha包中有hehe包,类文件存在hehe包中。称为:子父包。用于逐级存放,对包进行分层管理。调用时需要将全部包名写出。

   

 

    import导入关键字

    为了简化类名的书写,使用import关键字,导入包中的类文件,而不是子包,例如,import packb.pack10.DemoC;。如果一个包里面有多个类,可以使用通配符“*”代替这些类,例如,import packb.pack10.*;,全部导入主程序中。一般来说,只要将需要的类导入即可,无需全部导入,少用“*”。

    导入包中可能有重名类,这是不允许的。可以给类加上包名来区别不同的包的类。

    导入类的方式:直接通过包名导入;利用import导入。

 

    包名的规范:不要让包名重复,保持唯一性。可以使用url(域名)来完成定义,因为url是唯一的。例如,package cn.itcast.demo;。

 

    jar包

    java的压缩包,编译时通过工具jar.exe完成。例如,jar –cf haha.jar pack packa,将pach和packa包压缩为名为haha的jar包。查看包中的内容,例如:jar –tf haha.jar。也可以通过压缩工具winRAR打开,直接看。

    jar压缩包和rar压缩包的区别:将类封装进jar包后仍然可以运行。但是无法再更改、编译了,只能运行。

    方便项目的携带。

    方便使用,只要在classpath中设置jar包的路径即可。网络上也有这些资源,提供各种类使用,例如,阿帕奇。

    数据库驱动,SSH框架都是以jar包体现的。

    dos中命令使用:

    -cfv:创建jar包并列出内部情况

    -tvf:列出jar包的详细情况

    c:\> dir>c:\1.txt,将c盘的目录列表存放在1.txt文件中。数据重定项,即让数据在文件中显示。

    jar –tf rt.jar>c:\2.txt将这个包内容存在文件内。rt.jar是java的类库。

    将java中的一些工具压缩成exe包,例如javac,内部都是类文件,主程序是tools.jar中的一个类文件。D:\jdk1.6.0_10\lib中的tools.jar,编译所属的类都在此包中。java本身也是用类写成的,需要一个运行环境才能执行。

    src.zip是java所有类的源文件。

原创粉丝点击