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. win安装mysql

    在这讲解的是有关于通过zip解压安装MySQL的方法.有看了网上的其它的教程,讲的有些不够完善,也自己写一篇简述一下.个人还是建议看官方的参考文档非常之详细:https://dev.mysql.com ...

  2. Linux下如何执行Shell脚本

    Linux下你可以有两种方式执行Shell脚本: 1.用shell程序执行脚本:根据你的shell脚本的类型,选择shell程序,常用的有sh,bash,tcsh等(一般来说第一行#!/bin/bas ...

  3. [WorldWind学习]19.WebDownload

    using System; using System.Diagnostics; using System.Globalization; using System.Net; using System.I ...

  4. 详解PHP实现定时任务的五种方法

    这几天需要用PHP写一个定时抓取网页的服务器应用. 在网上搜了一下解决办法, 找到几种解决办法,现总结如下. 定时运行任务对于一个网站来说,是一个比较重要的任务,比如定时发布文档,定时清理垃圾信息等, ...

  5. 1124 Raffle for Weibo Followers[简单]

    1124 Raffle for Weibo Followers(20 分) John got a full mark on PAT. He was so happy that he decided t ...

  6. java基础知识面试题(1-40)

    1.面向对象的特征有哪些方面?答:面向对象的特征主要有以下几个方面:- 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不关注这些 ...

  7. CCPC-Wannafly Winter Camp Day5 (Div2, onsite)

    Replay: Dup4: 时间复杂度算不对? 一点点思路不经过验证就激动的要死? 浪费自己一个小时还浪费别人一个小时? 对1e3不敏感? 1e3 * 1e3是多少? 模拟建边跑dp不写非要写个大模拟 ...

  8. SQL: 查找空值

    ①用 IS NULL ②NULL 不能用 “=” 运算符 ③NULL 不支持加.减.乘.除.大小比较.相等比较 ④不同的函数对NULL的支持不一样,在遇到NULL时最好测试一下结果会受什么影响,不能仅 ...

  9. surface知识点

    SurfaceView和TextureView 在学习直播的过程遇到一个问题:连麦场景下能够支持大小窗口切换(即小窗口变大,大窗口变小),大窗口是TextView(用于拉流显示),而小窗口是Surfa ...

  10. Web前端学习笔记之前端跨域知识总结

    0x00 前言 相信每一个前端er对于跨域这两个字都不会陌生,在实际项目中应用也是比较多的.但跨域方法的多种多样实在让人目不暇接.老规矩,碰到这种情况,就只能自己总结一篇博客,作为记录. 0x01 什 ...