Java异常 Exception
异常指的的在运行期出现的错误,在编译阶段出现的语法错误等,不能称之为异常。

编译类异常

必须处理之后才能正常编译(类找不到,IO异常,在API文档中明确写明throws的方法,必须要进行处理)

运行时异常(RuntimeException)

这种异常可以处理也可以不处理。

运行时异常的解决方法

遇到错误终止程序的运行,即不对异常进行处理
由程序员在编写程序的时,就考虑到错误的检测、错误的消息的提示,在抛给Java运行环境的时候,就将这个异常对象捕获,在进行处理。
使用try/catch语句捕获异常对象

public class Exception1 {
        public static void main(String[] args){
            int[] arr = {1,2,3};
            try{
                System.out.println(arr[4]); //加上try语块
            }catch(Exception e){
                System.out.println("发生数组越界");
            }
        }
    }
try尝试:将可能发生异常的语句放入其中
catch捕获:当try块中的异常发生时,将产生一个异常对象,拿着这个对象去匹配catch块中的异常类,如果和catch中的类型匹配了,就执行这个catch块中的语句,这就是意味着,catch块可以有多个。

public class Exception2 {
    public static void main(String[] args){
        String str =null;
        try{
            System.out.println(str.length());
        }catch(NullPointerException e){
            System.out.println("空指针");
        }catch(Exception e){
            System.out.println("未知错误");
        }
    }
}
从程序上可以看出,一个try后可以加多个catch块,针对try语句块中发生的异常分别捕获,当然,只能有一个catch块碑执行,从执行的逻辑上看,和switch分支语句很相似。

进行异常捕获时,所有父类异常块都应该排在子类异常catch块的后面

访问异常信息

程序需要在catch块中访问异常对象的相关信息,可以通过访问catch块后的异常形参来获得,当Java运行时决定调用某个catch块来处理该异常对象时,会将异常对象赋值给catch块后的异常参数(即:异常类型的形参),程序即可通过该参数来获得异常的相关信息。

getMessage():返回该异常的详细描述信息
printStackTracwe():将异常的跟踪栈信息打印出来
printStackTrace(PrintStream s):将异常的跟踪栈信息输出到指定的输出流
getStackTrace():返回该异常的跟踪栈信息

import java.io.FileInputStream;   //导包
public class Exception3 {
    public static void main(String[] args){
        try{
            FileInputStream fis = new FileInputStream("aa");  
        }catch(Exception e){
            System.out.println(e.getMessage());  //打印异常信息
            e.printStackTrace();                    //打印跟踪信息
        } 
    }
}
编译时异常(必须捕获)

import java.io.FileInputStream;
    public class Exception4 {
        public static void main(String[] args){
            FileInputStream in = null;
            try{
                in = new FileInputStream("aa");
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
finally回收资源

完整的异常处理结构

try{
        业务处理语句
    }catch(异常1 e1){
        异常处理语句
    }catch(异常2 e2){
        异常处理语句
    }
    ...
    finally{
        资源回收语句
    }
注意:

在异常处理的机构中,只有try块是必须的,也就是说,如果没有try块,则不能有后面的catch和finally块,catch与finally二者中至少出现一个,当然也可以同时出现;finally位于所有catch块的后面

import java.io.FileInputStream;
    import java.io.IOException;

public class Exception5 {
        public static void main(String[] args){
            FileInputStream fis = null;
            try{
                fis = new FileInputStream("aa");
            }catch(IOException i){
                System.out.println("发生异常");
            }finally{
                System.out.println("总会执行");
            }
        }
    }
注意:System.exit(1);退出虚拟机 ####总结 - 除非在try块,catch块中调用了退出虚拟机的方法,否则不管在try块,catch块中执行怎样的代码,出现怎样的情况,finally块中的语句总会被执行。 - 通常情况下,不要在finally块中使用return或者throw等导致方法终止的语句,一旦在finally块中使用了return或者throw语句,将会导致try块,catch块中的return,throw语句失效。

public class Exception6 {
        public static void main(String[] args){
            int res = test();
            System.out.println(res);   //  打印结果为3
        }
        public static int test(){
            try{
                System.out.println(2/0);
                return 1;
            }catch(Exception e){
                return 2;
            }finally{
                return 3;
            }
        }
    }
Checked异常和Runtime异常体系

Checked异常:编译时异常
Runtime异常:运行时异常
对于Checked异常有两种处理方式:

当前方法明确知道该如何处理该异常,程序应该使用try/catch块来捕获该异常,然后在对应的catch块中进行修复异常
当前方法不知道如何处理该异常,应在方法声明时抛出该异常
Runtime异常处理方式:

Runtime异常无需明显式抛出,如果储蓄需要捕获Runtime异常,也可以使用try/catch块来实现。

使用throws声明抛出异常,是对异常的一种处理方式

当前方法不知道如何处理这种类型的异常,该异常应该由上一级的调用者处理;如果main方法也不知道如何处理这种类型的异常,也可以使用throws继续声明抛出,将该异常交给JVM处理。JVM对异常的处理方法是打印异常的跟踪栈信息,并终止程序运行。

throws声明抛出异常的语法格式

方法签名+ throws Exception1,Exception2...
一旦一个方法使用throws关键字声明抛出了该异常,程序就无需使用try/catch块来捕获该异常了

import java.io.*;
    public class Exception8 {
        public static void main(String[] args) throws Exception{  //继续将异常抛出,交由JVM处理
            test();
        }
        public static void test() throws Exception{   //抛出异常
            FileInputStream fis = new FileInputStream("aa");
        }
    }
在定义一个方法时,使用throws声明抛出异常有一个限制

方法重写时,子类方法声明抛出的异常类型应该是父类声明抛出的异常类型的子类或者相同,子类声明抛出的异常不允许比父类方法声明抛出的异常大

总结

使用checked异常有如下不方便的地方

对于checked异常,必须显示的捕获并处理该异常,或者显式的声明抛出该异常,这样无疑增加了编程的复杂度
如果方法中显式抛出checked异常将会导致方法签名与异常耦合在一起,如果该方法时重写父类的方法,则该方法抛出的异常还会受到被重写方法所抛出异常的限制
如何自行抛出异常

在程序中抛出异常的话,需要使用到throw语句

首先要生成异常类对象,其语法格式如下:

IOException e = new IOException();
    throw e;
对于Checked异常与Runtime异常的处理方法

如果throw语句抛出的异常为Checked异常,则该throw语句要么处于try块里显式捕获该异常,要么放在一个带throws声明抛出的方法中,即把该异常交给方法的调用者去处理;
如果throw语句抛出的是Runtime异常,则该语句无须放在try块中,也无须放在带throws声明的方法;

import java.io.IOException;
public class Exception9 {
    public static void main(String[] args){
        //被调用的checkedEx方法会抛出异常,并且是编译异常,必须用try,catch捕获,或者是在调用的方法上继续声明抛出
        try{
            checkedEx();
        }catch(Exception e){
             e.printStackTrace();
        }
        //被调用的方法会抛出运行时异常,可以完全不理会,由调用者处理,这里的调用者就是main方法
        runtimeEx();
    }
    //方法中抛出的异常是编译异常,必须要进行处理:要么放在try块中,要么在方法声明上加上抛出声明
    public static void checkedEx() throws IOException{  
        throw new IOException("checked Exception");
    }
    public static void runtimeEx(){
        //方法中抛出的异常是运行时异常,可以处理,也可以不理会
        throw new NullPointerException();
    }
}
方法抛出异常的流程图,以(IOException--编译异常)为例

自定义异常类

定义异常类时通常需要提供两个构造方法,一个是无参的,一个是带有一个字符串的构造方法,这个字符串将作为该异常对象的描述信息,也就是对异常对象的getMessage方法的返回值

自定义一个异常类的语法如下

public class MyException extends Exception{
            public MyException(){}  //空参构造
            public MyException(String s){// 有参构造  字符串作为信息传递
                super(s);  //调用父类Exception的构造方法
            }
        }
案例练习

/*
    编写应用程序EcmDef.java,接收命令行的两个参数,要求不能输入负数,计算两数相除。
    对数据类型不一致(NumberFormatException)
    缺少命令行参数(ArrayIndexOutOfBoundsException
    除0(ArithmeticException)
    及输入负数(EcDef 自定义的异常)进行异常处理。
    前几种异常,Java中都已经有相应的异常类了,但是最后一种对输入负数的异常,系统没有这样的异常定义,所以,这个异常应该是我们自定义的异常。
    提示: 
    (1)在主类(EcmDef)中定义异常方法(ecm)完成两数相除功能。
    (2)在main()方法中使用异常处理语句进行异常处理。
    (3)在程序中,自定义对应输入负数的异常类(EcDef)。
    (4)运行时接受参数 java EcmDef 20 10   
        //args[0]=“20” args[1]=“10”
    (5)Interger类的static方法parseInt(String s)将s转换成对应的int值。
    如int a=Interger.parseInt(“314”);    //a=314;
    复习如何使用API文档,查看Integer类的方法
    */
    public class Exception11 {
        public static void main(String[] args){
            try{
                int a = Integer.parseInt(args[1]);  
                int b = Integer.parseInt(args[2]);
                int res = dev(a,b);
                System.out.println(res);
            }catch(NumberFormatException nfe){
                System.out.println("数据类型不一致");
            }catch(ArrayIndexOutOfBoundsException a){
                System.out.println("缺少命令行参数");
            }catch(ArithmeticException ae){
                System.out.println("除数不能为0");
            }catch(MyException me){
                System.out.println(me.getMessage());
            }
        }
        public static int dev(int a,int b) throws MyException{
            if(a<0||b<0){
                throw new MyException("除数不能为负数");
            }
            return a/b;
        }
    }
    //自定义异常类
    class MyException extends Exception{
        public MyException(){}
        public MyException(String s){
            super(s);
        }
    }

java基础第10天的更多相关文章

  1. JAVA基础(10)——IO、NIO

    转载:http://blog.csdn.net/weitry/article/details/52964948 JAVA基础系列规划: JAVA基础(1)——基本概念 JAVA基础(2)——数据类型 ...

  2. 夯实Java基础系列10:深入理解Java中的异常体系

    目录 为什么要使用异常 异常基本定义 异常体系 初识异常 异常和错误 异常的处理方式 "不负责任"的throws 纠结的finally throw : JRE也使用的关键字 异常调 ...

  3. Java基础语法(10)-面向对象之三大特征

    title: Java基础语法(9)-面向对象之类的成员 blog: CSDN data: Java学习路线及视频 1.面向对象特征--封装 为什么需要封装?封装的作用和含义? 我要用洗衣机,只需要按 ...

  4. Java 基础【10】 I/O流概念分析整理

    转载地址:http://blog.csdn.net/yuebinghaoyuan/article/details/7388059 java.io 中的流,可以从不同的角度进行分类. 按照数据流的方向不 ...

  5. Java基础教程(10)--类

    一.声明类   你已经见过了以如下方式定义的类: class MyClass { // field, constructor, and method declarations }   上面是声明类的最 ...

  6. Java基础(10)——小结与填坑

    前面都写了9篇啦,虽然断断续续发了半个月,写着写着会发现每篇中都有些比较重要的地方没有讲到~这篇还是需要填一填目前我已发现的坑了~ 一. 小结 Java编译命令 javac.运行命令java java ...

  7. java基础练习 10

    import java.util.Scanner; public class Tenth { /*有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面的m个数*/ public stati ...

  8. 【Java基础】10、Java中throw和throws的区别

    系统自动抛出的异常 所有系统定义的编译和运行异常都可以由系统自动抛出,称为标准异常,并且 Java 强烈地要求应用程序进行完整的异常处理,给用户友好的提示,或者修正后使程序继续执行. 语句抛出的异常  ...

  9. JAVA基础--异常10

    一.Object类简介 1.Object类简介 Object,是Java一切对象的最高父类:如果一个类没有显示继承一个类,他的父类就是Object: 它描述的是Java世界里所有对象最最共性的信息,它 ...

随机推荐

  1. 【selenium】selenium ide的安装过程

    简介一:SeleniumIDE安装 1.安装seleniumIDE,打开火狐浏览器,地址栏输入地址—>点击Add按钮—>安装结束后重启FireFox—>在菜单栏中可以看到Seleni ...

  2. Mirror--镜像用户同步

    --=========================================--在镜像搭建后,在主库服务器上创建登录,并在数据库上建立对应用户,--数据库中用户被同步到镜像数据库中,但登录是 ...

  3. Apache配置虚拟主机后让其他电脑访问

    关于Apache配置虚拟主机后在局域网中让其他电脑访问 #test1# NameVirtualHost *:80         ServerName  www.t1.com     Document ...

  4. Mybatis的CRUD案例

    一.Mybatis增删改查案例 上一节<Mybatis入门和简单Demo>讲了如何Mybatis的由来,工作流程和一个简单的插入案例,本节主要继上一讲完整的展示Mybatis的CRUD操作 ...

  5. testng生成报告ReportNG美化测试报告

    testng生成报告ReportNG美化测试报告 testng生成报告ReportNG美化测试报告 ReportNG 是一个配合TestNG运行case后自动帮你在test-output文件内生成一个 ...

  6. ReactNative生成android平台的bundle文件命令

    ReactNative生成android平台的bundle文件命令 2016年11月03日 23:23:28 阅读数:4869 注:如果assets文件没有正确生成,需要手机创建或授权 网上的其它的很 ...

  7. Winform开发之ComboBox和ComboBoxEdit控件绑定key/value数据

    使用 ComboBox 控件绑定key/value值: 因为 ComboBox 是有 DataSource 属性的,所以它可以直接绑定数据源,如 DataTable.ListItem 等. 使用 Da ...

  8. EditPlus 4.3.2463 中文版已经发布(10月16日更新)

    距离上个版本在本年5月发布后,EditPlus 网站沉寂多月.日前终于发布了一个新的小版本. 该版本却具有多项改进,值得一提: * Ctrl+Alt+Up/Down 键在列选模式下可插入多个插入点. ...

  9. .net webform 把word转为html

    首先添加引用 引用命名空间 using Microsoft.Office.Interop.Word; using System; using System.Collections.Generic; u ...

  10. 20145311实验二 "Java面向对象程序设计"

    20145311实验二 "Java面向对象程序设计" 程序设计过程 实验内容 使用单元测试.TDD的方式设计实现复数类 Complex 编写代码: 1.首先设计实现复数类 Comp ...