掌握:一个图(分类)、五个关键字(try catch finally throws throw)

一、概念

定义:

异常指的是运行期出现的错误(如除0溢出,空指针,数组/字符串下标越界,所要读取的文件不存在),它中断了正在执行的程序的正常指令流。

良好的程序应该在异常发生时提供处理方法,使得程序不会因为异常的发生而阻断或产生不可预见的结果。

补充知识:c和c++中不检查数组越界??如果程序员也没有自己处理数组越界,会存在缓冲区溢出的漏洞,这可能被黑客利用来更改保存现场时的程序地址,运行黑客程序。

二、异常的分类

  Throwable是异常的根类。其中,Error类是系统错误(虚拟机错误),我们处理不了的异常;Exception是所有异常类的父类,我们能够处理的,可以catch。Exception中的RuntimeException(也就是uncheckException)是经常出现的错误(如a/b,数组越界等),这种错误系统可以自动检测并处理,可以catch,也可以不catch;其他错误(如IO错误等)必须catch(常见的是JDK中的类方法中写了throws的Exception)。

例1:public static int parseInt(String s,int radix)throws NumberFormatException

  所抛出的异常NumberFormatException属于RuntimeException。但是如果程序中不用try-catch处理,虽然可以运行,但是抛出异常后面的语句则无法运行了。

  如果用try-catch处理,则抛出异常后,程序依然可以向下运行。

public class Test{
public static void main(String args[]){
try{
String str = "lili";
System.out.println(str+"年龄是:");
int age = Integer.parseInt("20L");
System.out.println(age);
}catch(Exception e){
//System.out.println(e.getMessage());
System.out.println(e.toString());
//e.printStackTrace();
}
System.out.println("program over"); //不使用try-catch则不输出本句话
}
}

输出:

lili年龄是:
java.lang.NumberFormatException: For input string: "20L"
program over

例2:对于不是RuntimeException的异常。必须写try-catch或用throws向上抛出。否则无法通过编译。如IOException。

三、异常的处理方法

  Java程序执行过程中,如果出现异常事件,可以生成一个异常类对象,该异常对象封装了异常事件的信息并将被提交给Java运行时系统,这个过程成为抛出(throw)异常;当Java运行时系统接收到异常对象时,会寻找能够处理这一异常的代码(try-catch),并把当前异常对象交给其处理,这一过程成为捕获(catch)异常;如果没有catch,那么系统自己按照默认方式处理(printStackTrace()方法,打印错误的堆栈信息)。

  某个方法抛出异常,既可以在当前方法中try-catch捕获后处理;也可以用throws将异常继续向上抛出,由方法调用者来处理。

1、在当前方法中捕获后处理

  异常产生后,如果不做任何处理,程序就会终止,不再执行下面语句。异常捕获结构由try,catch,finally三部分组成。

注意:执行完catch代码块后,继续执行catch代码块后面的的语句,但不会执行try中发生异常语句之后的语句。由此可见,这样就不会因为一个异常影响整个程序的执行。

注意:catch中一定要做出相应处理,哪怕是打印信息也行!多个catch语句时,注意先捕获子类异常再捕获基类异常。

(1)异常处理中3个常用函数:

getMessage()            //错误的性质

toString()                 //异常的类型和性质

printStackTrace()      //输出异常的类型、性质、栈层次、出现在程序中的位置

(2)finally语句

  完整的异常处理语句一定要包含finally,finally是总会执行的语句。除非以下四种特殊情况发生,finally才不会执行:

(1)在finally语句块中发生了异常

(2)在前面代码中用了System.exit()退出程序

(3)程序所在的线程死亡

(4)关闭CPU

注意:前面的代码中就算有return语句,finally还是会执行!

2、在方法中抛出异常(将异常继续向上抛出)

  若某个方法可能发生异常,但不想在当前方法中处理这个异常,那么可以使用throws关键字声明方法抛出异常。

(1)throws应用于声明方法时,用来指定方法可能抛出的异常,多个异常用逗号分隔。

  只用throws将异常向上抛出后,如果不想在上一级处理则可以继续抛出,但是最终要有能够处理该异常的代码。

注意:Error,RuntimeException及它们的子类,可以不用throws抛出。但运行时会被系统抛出。

注意:main方法中throws抛出异常非常不好!

(2)异常对象的产生途径有两种:JVM自动生成的和throw手动生成的。也就是说:throw并不是必须的,它一般用于抛出用户自定义异常。

  throw用于方法体中,抛出一个异常对象。throw通常用来抛出用户自定义异常。程序执行到throw时立即终止,它后面的语句都不再执行。

  通过throw抛出异常后,如果想在上一级捕获处理,则需要在抛出异常的方法中使用throws声明;如果要捕获throw抛出的异常,则必须使用try-catch。(必须catch处理的异常)

四、用户自定义的异常

  自定义异常,只需要继承Exception类即可。使用自定义异常类,分一下几步:

(1)通过继承Exception类或RuntimeException类创建自定义异常类

(2)在方法中通过throw抛出异常对象

(3)如果在当前抛出异常的方法中处理异常,可以使用try-catch

(4)否则在方法声明处使用throws向上抛出,在出现异常方法的调用者中使用try-catch

public class Test{
static int quotient(int x,int y) throws MyException{
if(y<0){
throw new MyException("除数不能为负");
}
return x/y;
}
public static void main(String args[]){
try{
int result = quotient(3,-1);
}catch(MyException e){
System.out.println(e.getMessage());
}catch(ArithmeticException e){
System.out.println("除数不能为0");
}catch(Exception e){
System.out.println("其他错误");
}
}
}
class MyException extends Exception{
String message;
public MyException(String s){
message = s;
}
public String getMessage(){//重写getMessage()方法
return message;
}
}

输出:

除数不能为负

五、重写与异常

class A{
protected void fun(int a,int b) throws IOException{
}
} class B extends A{
public void fun(int a,int b) throws FileNotFoundException{
}
}

总结:关于java中方法重写(override)的要求:
     1、子类中的方法与父类中的方法有相同的返回类型(例如:一个是int,一个是float,则编译出错)
     2、子类中的方法与父类中的方法有相同的方法名称
     3、子类中的方法与父类中的方法有相同的参数列表
     4、子类中的方法的访问级别不能低于父类中该方法的访问级别(举例:父类方法的级别是protected,那么子类重写该方法,其级别必须是protected或者public,一定和父类的访问级别相同或者更宽,否则编译无法通过)
     5、子类中方法抛出的异常范围不能大于父类中方法抛出的异常的范围。

  即重写方法需要抛出与原方法所抛出异常类型一致的异常(相同的异常或子类的异常)或不抛出异常。不能抛出新异常!如果父类不抛异常,子类不能抛异常!

如:原来抛出IOException,重写后抛出FileNotFoundException,但不能抛出Exception(编译出错!)。

个人理解:后两条是为了保证程序的可扩展性。例如一个方法之前没有被重写,现在在其子类中重写该方法:如果子类中的访问权限低于父类,就有可能造成上层调用者无法访问该重写方法的情况;再如如果一个方法重写后抛出的异常是之前父类方法中不包括的类型,那么可能造成调用者无法处理该异常的情况。

JAVA笔记13-异常处理Exception的更多相关文章

  1. java 异常和异常处理Exception

    Java Exception: 1.Error 2.Runtime Exception 运行时异常3.Exception 4.throw 用户自定义异常 异常类分两大类型:Error类代表了编译和系统 ...

  2. Thinking in Java——笔记(13)

    Strings Immutable Strings Objects of the String class are immutable. Every method in the class that ...

  3. Java笔记13:统计文件中每个字符出现的次数

    一.代码实现 import java.io.*; import java.util.*; /** 功能:统计文件中每个字符出现的次数 思路: 1.定义字符读取(缓冲)流 2.循环读取文件里的字符,用一 ...

  4. java笔记13之成员变量与局部变量

    成员变量和局部变量的区别 1在类中的位置不同 局部变量:类的方法体内 成员变量:类的方法之外 2内存的不同位置 局部变量:在栈内存中 成员位置:在堆内存 3生命周期不同 局部变量:随着方法的调用而存在 ...

  5. java异常处理Exception

    我看别人的面经中有一道题目就问到了Exception,即java的异常处理的,我曾经也学了java的异常处理,可是我查了下,看了别人的博客关于写的exception异常处理.我发现,自己学的不坚固,仅 ...

  6. JAVA自学笔记13

    JAVA自学笔记13 1.StringBuffer类 1)线程安全的可变字符序列 线程安全(即同步) 2)StringBuffer与String的区别:一个可变一个不可变 3)构造方法: ①publi ...

  7. Java 学习笔记(11)——异常处理

    异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的. 比如说,你的代码少了一个分号,那么运行出来结果是提示是错误 java.lang.Error:如果你用System.ou ...

  8. java笔记整理

    Java 笔记整理 包含内容     Unix Java 基础, 数据库(Oracle jdbc Hibernate pl/sql), web, JSP, Struts, Ajax Spring, E ...

  9. Java笔记(二十六)……IO流上 字节流与字符流

    概述 IO流用来处理设备之间的数据传输 Java对数据的操作时通过流的方式 Java用于操作流的对象都在IO包中 流按操作的数据分为:字节流和字符流 流按流向不同分为:输入流和输出流 IO流常用基类 ...

  10. Core Java笔记

    前言 一·基础知识 二·定义,关键字和类型 三·表达式和控制流 四·数组 五·对象和类 六·高级语言特性 七·异常 八·图形用户接口 九·AWT(Abstract Window Toolkit) 事件 ...

随机推荐

  1. UniEAP Platform V5.0 Unable to compile class for JSP

    流程设计器报错: http://127.0.0.1:8080/framework/workflow/webdesign/procmodify/procmodifydetail.jsp?isLoadDa ...

  2. java:Review(J2ee)

    1.oracle: 1.1 增:insert into 删:delete from 改:update tablename set 查:select * from 1.2 聚合函数 max,min,av ...

  3. java:JSP(JSPWeb.xml的配置,动态和静态导入JSP文件,重定项和请求转发,使用JSP实现数据库的增删改查实例)

    1.JSP的配置: <%@ page language="java" import="java.util.*" pageEncoding="UT ...

  4. 奥比中光Astra Pro在ROS系统中的使用

    奥比中光Astra Pro在ROS系统中的使用 上一次介绍了Astra Pro在ubuntu中的使用,由于Astra Pro使用uvc传输彩色图像,所以当用rqt_image_view窗口 时,看不到 ...

  5. CodeSmith 找不到请求的 .Net Framework Data Provider

    连接数据库时候报标题的错误解决方案 安装mysql-connector-net-6.8.7.msi,下载地址:http://dev.mysql.com/downloads/connector/net/ ...

  6. mysql——单表查询——聚合函数——概念

    使用聚合函数查询 group by关键字通常和聚合函数一起使用 .count()函数 count()函数用来统计记录的条数 举例:使用count()函数统计employee表的记录数 select c ...

  7. Akka系列(四):Akka中的共享内存模型

    前言...... 通过前几篇的学习,相信大家对Akka应该有所了解了,都说解决并发哪家强,JVM上面找Akka,那么Akka到底在解决并发问题上帮我们做了什么呢? 共享内存 众所周知,在处理并发问题上 ...

  8. [ASP.NET] 解决因为使用 updatepanel 导致 fileupload 始终无法获取文件的方法

    接手了一个新项目,需要在老项目中增添几个新页面 由于在母版页中的updatepanel包住了子版页 同时updatepanel并不支持文件上传,因此要额外增加一些设置 具体的情况可以参考这篇博客 ht ...

  9. Vue 子组件,向父组件传递。

  10. 在 IntelliJ IDEA 中使用 Git,太方便了!

    git是目前流行的分布式版本管理系统.它拥有两套版本库,本地库和远程库,在不进行合并和删除之类的操作时这两套版本库互不影响.也 因此其近乎所有的操作都是本地执行,所以在断网的情况下任然可以提交代码,切 ...