首页 > 其他 > 详细

异常的一系列和final finally finalize

时间:2021-05-03 22:18:25      阅读:29      评论:0      收藏:0      [点我收藏+]

异常

什么是异常,java提供异常处理机制有什么用

以下程序执行过程之中发生了不正常的情况,而这种不正常的情况:叫做异常

java语言是很完善的语言,提供了异常处理方式,以下程序执行过程中出现了不正常情况,

java把该异常信息打印输出到控制台,供程序员参考,程序员看到信息后,可以对程序进行修改,让程序更加健壮

技术分享图片

 

  • 异常:程序执行过程中的不正常情况

  • 异常的作用:增强程序的 健壮性

java语言中 异常是以什么样的形式存在的

  • 异常在java中以类的形式存在

    • 实际上jvm在执行到异常的时候,会new异常对象,:new ArithmeticException(”/ by zero“);

    • 并且jvm将new的异常对象抛出,打印输出信息到控制台上


     

  • 类:模板

  • 对象:实际存在的个体


java的异常处理机制

  • 异常在java 中以类和对象的形式存在,我们可以使用UML图来描述一下继承机构

画UML图有很多工具,例如Rational Rose(收费)、starUML等……

  • UML是一种统一的建模语言

UML不是只有java中使用,只要是面对对象的编程语言,都有UML

一般画UML图的都是软件架构师,或者说是系统分析师,这些级别的人员使用的

软件 设计人员使用UML

  • 在UML图中可以描述类和类之间的关系,程序执行的流程,对象的状态等

 

所有的错误,只要发生,

技术分享图片

 

 

exceptionSubClass Exception的直接子类:所有Exception的直接子类。都叫做编译时异常、编译时异常是在编译阶段发生的吗?不是。编译时异常是表示必须在编写程序的时候预先对这种异常进行处理,如果不处理,编译器报错

发生概率较高 ;又被称为受检异常 受控异常

 

RuntimeException 运行时异常在编写程序阶段,你可以选择处理,也可以不处理

发生概率较低 ; 未受检异常,未受控异常


  • 编译时异常和运行时异常,都是发生在异常阶段,编译阶段异常是不会发生的,编译时异常因为什么而得名?因为编译时异常必须在编译(编写)阶段预先处理,如果不处理编译器报错。以此得名

所有异常都是在运行阶段发生的,因为只有程序运行阶段才可以new对象。因为异常的发生就是new异常对象。

  • 编译时异常和运行时异常的区别

    • 编译时异常一般发生的概率比较高。

     

    • 运行时异常一般发生概率比较低

  • java语言中对异常的两种处理方式

    • 第一种方式:在方法声明的位置上,使用throw关键字,抛给上一级

    谁调用我,我就抛给谁,抛给上一级。

    • 第二种方式:使用户try。。catch语句进行异常的捕捉。

    这件事发生了,谁也不知道,因为我给抓住了。

举个例子:技术分享图片

  • 注意:java中异常发生之后如果一直上抛,最终抛给了main方法,main方法继续向上抛,抛给了调用者jvm,jvm知道这个异常发生,只有一个结果,终止java程序的执行。


  • ArithmeticException继承RuntimeException,属于运行时异常。

在编写程序阶段不需要对这种异常进行预先处理。

 

 

技术分享图片

 

上抛类似于推卸责任,(继续把异常传递到调用者)、

捕捉等于把异常拦下来,异常真正的解决了(调用者不知道的)

 

处理异常的第一种方式:在方法声明的位置上使用throw关键字抛出,谁调用我这个方法,我就抛给谁,抛给调用者来处理。

技术分享图片

处理异常的第二种方式:

技术分享图片

 

 

  • 一般不建议在main方法上使用throw,因为这个异常如果真正发生了,一定会抛给jvm,jvm只有终止,异常处理机制的作用就是增强程序的健壮性,异常发生了也不影响程序的执行,所以一般main方法中的异常建议使用try 。。 catch进行捕捉,main就不要继续上抛了。

 

注意:只要异常没有捕捉,采用上报的方式,此方法的后续方法不会执行

另外需要注意,try语句块中的某一行出现异常,该行后面的代码不会执行

try。。catch 捕捉异常之后,后续代码,可以执行


 

一个方法体当中的代码出现异常之后,如果采用上报的话,此方法结束;

 

深入try catch

技术分享图片

多态,catch后面可以写确切类型,也可以是该异常类型的父类型(多态)

 

catch可以写多个,建议catch的时候,精确的一个一个处理,这样有利于程序的调试

catch写多个的时候,从上到下,必须遵守从小到大。


 

技术分享图片

jdk8 的新特性,异常可以采用或的符号来进行catch


以后的开发中,处理编译时异常,应该上报还是捕捉?

  • 如果希望调用者来处理,选择throw上报

  • 其他情况下使用捕捉。

 

捕捉了异常.后面的程序不会耽误执行,很健壮,(服务器不会遇到异常而宕机)

 

看异常信息,从上往下一行一行看,但要注意sun公司写的代码就不用看了(看包名)

 

catch(FileNotFoundException e){
   e.printStackTrace();
       //这行代码要写上,不然出现问题你也不知道
}

getMessage和printStackTrace

技术分享图片

一般使用下面的异常打印

上面的是简短的异常信息

 

finally

  • 在finally子句中的代码是最后执行的,并且是一定会执行的,即使try语句块中的代码出现了异常,finally子句必须和try一起出现,不能单独编写

  • finally语句通常使用在哪些情况下

通常finally语句块中完成资源的释放和关闭

因为finally中的代码比较有保障

即使try语句块中的代码出现异常,finally中的代码也会执行

技术分享图片

退出jvm虚拟机之后finally中的代码还是不会执行的

技术分享图片

 

放在finally的语句是一定会执行的

即使try里面有return,finally中的语句也会执行

System.exit(0);不会执行

 

 

面试题

技术分享图片

  • java语法规则:(有一些规则是不能破坏的,一旦这么说了,就必须那么做!):

java中有一条这样的规则:

方法体中的代码必须遵循自上而下的顺序依次逐行执行(亘古不变的语法)

java中还有一条语法规则:

return一旦执行,整个方法必须结束(亘古不变的语法)

final finally finalize有什么区别

  • final 是一个关键字,表示最终的,不会变的。

  • finally也是一个关键字,和try联合使用,使用在异常处理机制中,在finally语句块中的代码是一定会执行的。

  • finalize()是object类中的一个方法,作为方法名出线,所有finalize是标识符

finalize()方法是jvm的gc垃圾回收器负责调用的

技术分享图片

如何自定义异常

sun提供的jdk内置异常肯定是不够用的,在实际的开发中,有很多业务

这些义务出现异常之后,jdk中都是没有的,和业务挂钩,所以要自定义异常

  • 怎么自定义异常:

两步: 第一步:编写一个类继承Exception(编译时异常)或者RuntimeException(运行时异常)

第二部:提供两个构造方法,一个无参数,一个带String参数的

死记硬背

技术分享图片

技术分享图片

如何使用自定义异常

技术分享图片

技术分享图片

自定义异常在开发中的作用’


 

  • 之前在讲解方法覆盖的时候,当时遗留了一个问题?

    重写之后的方法,不能比重写之前的方法抛出更多的(更宽泛的)异常。可以更少

     


总结异常中的关键字

异常捕捉

  • try

  • catch

  • finally

 

  • throws 在方法声明位置上使用,表示上报异常信息给调用者

  • throw 手动抛出异常

     

作业

  • 引用==null的这个判断最好放在所有条件的最前面

  • 再分享一个经验:username==null 不如写成 null== username

“ABC”.equal(username) 比username.equals("abc")好

package com.zhang.jun.jia;
?
public class HomeWorkyichang {
   public void register(String username,String password) throws illegalException {
       if (username == null||username.length()<3||username.length()>10){
         /* illegalException exception = new illegalException("用户名命名不规范");
           throw exception;*/
           throw new illegalException("用户名不合法,应该在3到10之间")
      }
       System.out.println("欢迎使用" +
               "注册成功");
?
  }
?
}
?

 

自定义异常:

package com.zhang.jun.jia;
?
public class illegalException  extends Exception{
   public illegalException() {
  }
?
   public illegalException(String message) {
       super(message);
  }
}
?

 

 

武器库的题目

package com.zhang.jun;
?
public class Test {
   public static void main(String[] args) throws AddWeapon {
       Army army = new Army(3);
?
       Paota paota =new Paota();
       Tunk tunk =new Tunk();
       Yunshuche yunshuche =new Yunshuche();
       Plane plane = new Plane();
?
       try {army.addWeapon(plane);
           army.addWeapon(paota);
           army.addWeapon(tunk);
           army.addWeapon(yunshuche);
?
      }catch (AddWeapon e){
           System.out.println(e.getMessage+"出错了,添加武器失败了");
      }
?
?
?
?
       army.moveall();
       army.attackall();
?
  }
}
?
package com.zhang.jun;
?
public class Army {
   private Weapon[] weapons;
?
   public Army(int count) {
       weapons = new Weapon[count];
       for (int i =0;i<count;i++){
           weapons[i]=null ;
      }
  }
   public void addWeapon(Weapon weapon) throws AddWeapon {
       for (int i =0;i <weapons.length;i++)
      {
           if (null == weapons[i]){
               weapons[i]=weapon;
               return;
          }
?
      }throw new AddWeapon("武器放满了,放不下了");
?
  }
   public void attackall(){
       for (int i = 0; i<weapons.length;i++){
           if (weapons[i]instanceof shootable)
          {
               shootable shootable = (shootable) weapons[i];
               shootable.shoot();
          }
      }
?
?
  }
   public void moveall(){
       for (int i = 0; i<weapons.length; i++){
           if (weapons[i]instanceof Moveable)
          {
               Moveable moveable = (Moveable) weapons[i];
               moveable.move();
          }       }
  }
}
?

两个接口的定义

?
package com.zhang.jun;
?
public interface shootable {
   //射击动作
   void shoot ();
}
?
=================================================================
package com.zhang.jun;
?
public interface Moveable {
   void move();
}
?
?

 

 

  • 类在强制类型转换过程中,如果类转换成接口类型,

那么类和接口之间不需要存在继承关系,也可以转换,java语法中允许

 

异常的一系列和final finally finalize

原文:https://www.cnblogs.com/geren/p/14728014.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!