疾速入门

将可能出现异常的代码块选中->快捷键 ctrl + alt + t -> 选中 try-catch

package com.hspedu.exception_;public class Exception01 {    public static void main(String[] args)  {        int num1 = 10;        int num2 = 0;//Scanner();        //2. 当执行到 num1 / num2 因为 num2 = 0, 程序就会呈现(抛出)异样 ArithmeticException        //3. 当抛出异样后,程序就退出,解体了, 上面的代码就不再执行        //4. 不应该呈现了一个不算致命的问题就导致整个零碎解体        //5. java 设计者,提供了一个叫异样解决机制来解决该问题        //如果程序员,认为一段代码可能出现异常/问题,能够应用try-catch异样解决机制来解决,从而保障程序的健壮性        //将该代码块->选中->快捷键 ctrl + alt + t -> 选中 try-catch        //6. 如果进行异样解决,那么即便呈现了异样,程序能够继续执行        try {            int res = num1 / num2;        } catch (Exception e) {            //e.printStackTrace();            System.out.println("出现异常的起因=" + e.getMessage());//输入异样信息        }        System.out.println("程序持续运行....");    }}

异样介绍

Java语言中,将程序执行中产生的不失常状况称为“异样”。(开发过程中的语法错误和逻辑谬误不是异样)

执行过程中所产生的异样事件可分为两大类:

1.Error(谬误):Java虚拟机无奈解决的重大问题。如:JVM零碎外部谬误、资源耗尽等重大状况。比方: StackOverflowError[栈溢出] 和 OOM(out of memory).

Error是严重错误,程序会解体。

2.Exception:其它因编程谬误或偶尔的外在因素导致的一般性问题,能够应用针对性的代码进行解决。例如空指针拜访,试图读取不存在的文件,网络连接中断等等,Exception分为两大类:

  • 运行时异样[程序运行时,产生的异样]
  • 编译时异样[编程时,编译器查看出的异样]

异样体系图一览!

异样体系图

异样体系图的小结

  1. 异样分为两大类,运行时异样和编译时异样.
  2. 运行时异样,编译器查看不进去。个别是指编程时的逻辑谬误,是程序员应该防止其呈现的异样。java.lang.RuntimeException 类及它的子类都是运行时异样。
  3. 对于运行时异样,能够不作解决,因为这类异样很广泛,若全解决可能会对程序的可读性和运行效率产生影响。
  4. 编译时异样,是编译器要求必须处理的异样。

常见的运行时异样

常见的运行时异样包含

1) NullPointerException 空指针异样
2) ArithmeticException 数学运算异样
3) ArrayIndexOutOfBoundsException 数组下标越界异样
4) ClassCastException 类型转换异样
5) NumberFormatException 数字格局不正确异样[]

常见的运行时异样举例

  1. NullPointerException 空指针异样
    当应用程序试图在须要对象的中央应用null 时,抛出该异样。

    public class NullPointerException_ { public static void main(String[] args) {   String name = null; // 空指针出现异常   System.out.println(name.length()); }}
  2. ArithmeticException 数学运算异样

    当出现异常的运算条件时,抛出此异样。例如,一个整数“除以零”时,抛出此类的一个实例。

3) ArrayIndexOutOfBoundsException 数组下标越界异样
用非法索引拜访数组时抛出的异样。如果索引为负或大于等于数组大小,则该索引为非法索引。

  1. ClassCastException 类型转换异样
    当试图将对象强制转换为不是实例的子类时,抛出该异样。例如,以下代码将生成一个ClassCastException

    public class ClassCastException_ { public static void main(String[] args) {   A b = new B(); //向上转型   B b2 = (B)b;//向下转型,这里是OK   C c2 = (C)b;//这里抛出ClassCastException }}class A {}class B extends A {}class C extends A {}
  2. NumberFormatException 数字格局不正确异样
    当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格局时,抛出该异样=> 应用异样咱们,能够确保输出是满足条件数字.

    public class NumberFormatException_ { public static void main(String[] args) {   String name = "timerring";   //将String 转成 int   int num = Integer.parseInt(name); // 抛出NumberFormatException   System.out.println(num); }}

编译异样

编译异样是指在编译期间,就必须解决的异样,否则代码不能通过编译。

常见的编译异样

SQLException:操作数据库时,查问表可能产生异样

IOException:操作文件时,产生的异样

FileNotFoundException:当操作一个不存在的文件时,产生异

ClassNotFoundException:加载类,而该类不存在时,异样

EOFException:操作文件,到文件开端,产生异样

lllegalArguementException :参数异样

异样解决

根本介绍

异样解决就是当异样产生时,对异样解决的形式。

异样解决的形式

1) try-catch-finally:程序员在代码中捕捉产生的异样,自行处理

2) throws:将产生的异样抛出,交给调用者(办法)来解决,最顶级的解决者就是JVM。

示意图

如果程序员没有显示地解决异样,则默认是throws。

try-catch 异样解决

try-catch 形式解决异样阐明

  1. Java提供try和catch块来解决异样。try块用于蕴含可能出错的代码。catch块用于解决try块中产生的异样。能够依据须要在程序中有多个try...catch块。
  2. 根本语法

    try { //可疑代码 //将异样生成对应的异样对象,传递给catch块}catch(异样){ //对异样的解决}//如果没有finally,语法是能够通过

try-catch 形式解决异样细节

  1. 如果异样产生了,则异样产生前面的代码不会执行,间接进入到catch块。
  2. 如果异样没有产生,则程序执行try的代码块,不会进入到catch。
  3. 如果心愿不论是否产生异样,都执行某段代码(比方敞开连贯,开释资源等)
    则应用如下代码 finally {}
  4. 能够有多个catch语句,捕捉不同的异样(进行不同的业务解决),要求父类异
    常在后,子类异样在前,比方( Exception 在后,NullPointerException 在前),如果产生异样,只会匹配一个catch。(因为如果在后面都让Exception捕捉了,前面写子类捕捉就没有用了)。

    package com.hspedu.try_;public class TryCatchDetail02 {    public static void main(String[] args) {                //1.如果try代码块有可能有多个异样        //2.能够应用多个catch 别离捕捉不同的异样,相应解决        //3.要求子类异样写在后面,父类异样写在前面        try {            Person person = new Person();            //person = null;            System.out.println(person.getName());//NullPointerException            int n1 = 10;            int n2 = 0;            int res = n1 / n2;//ArithmeticException        } catch (NullPointerException e) {            System.out.println("空指针异样=" + e.getMessage());        } catch (ArithmeticException e) {            System.out.println("算术异样=" + e.getMessage());        } catch (Exception e) {            System.out.println(e.getMessage());        } finally {        }    }}class Person {    private String name = "jack";    public String getName() {        return name;    }}
  5. 能够进行try-finally配合应用,这种用法相当于没有捕捉异样,因而程序会
    间接崩掉/退出。利用场景就是执行一段代码,不论是否产生异样,都必须执行某个业务逻辑。

    public class TryCatchDetail03 {    public static void main(String[] args) {        /*        能够进行 try-finally 配合应用, 这种用法相当于没有捕捉异样,        因而程序会间接崩掉/退出。利用场景,就是执行一段代码,不论是否产生异            常,都必须执行某个业务逻辑         */        try{            int n1 = 10;            int n2 = 0;            System.out.println(n1 / n2);        }finally {            System.out.println("执行了finally.."); // 执行完间接退出        }        System.out.println("程序继续执行.."); // 不会执行    }}

练习

package com.hspedu.try_;public class TryCatchExercise01 {}class Exception01 {    public static int method() {        try {            String[] names = new String[3];//String[]数组            if (names[1].equals("tom")) {//NullPointerException                System.out.println(names[1]);            } else {                names[3] = "hspedu";            }            return 1;        } catch (ArrayIndexOutOfBoundsException e) {            return 2;        } catch (NullPointerException e) {//捕捉            return 3; // 然而不从这里返回        } finally {  // 必须执行,相当于没有异样捕捉            return 4; // 返回4        }    }    public static void main(String[] args) {        System.out.println(method()); // 输入4    }}
package com.hspedu.try_;public class TryCatchExercise03 {}class ExceptionExe01 {    public static int method() {        int i = 1;//i = 1        try {            i++;// i=2            String[] names = new String[3];            if (names[1].equals("tom")) { //空指针                System.out.println(names[1]);            } else {                names[3] = "hspedu";            }            return 1;        } catch (ArrayIndexOutOfBoundsException e) {            return 2;        } catch (NullPointerException e) {            return ++i;  // i = 3 => 保留长期变量 temp = 3;        } finally {            ++i; //i = 4            System.out.println("i=" + i);// i = 4        }    }    public static void main(String[] args) {        System.out.println(method());// 3    }}// 最终输入 i = 4    3

try-catch-finally 执行程序小结

1) 如果没有出现异常,则执行try块中所有语句,不执行catch块中语句,如果有finally,最初还须要执行finally外面的语句。
2) 如果出现异常,则try块中异样产生后,try块剩下的语句不再执行。将执行catch块中的语句,如果有finally,最初还须要执行finally外面的语句。

课后练习题

如果用户输出的不是一个整数,就提醒他重复输出,直到输出一个整数为止

package com.hspedu.try_;import java.util.Scanner;public class TryCatchExercise04 {    public static void main(String[] args) {        //如果用户输出的不是一个整数,就提醒他重复输出,直到输出一个整数为止        //思路        //1. 创立Scanner对象        //2. 应用有限循环,去接管一个输出        //3. 而后将该输出的值,转成一个int        //4. 如果在转换时,抛出异样,阐明输出的内容不是一个能够转成int的内容        //5. 如果没有抛出异样,则break 该循环        Scanner scanner = new Scanner(System.in);        int num = 0;        String inputStr = "";        while (true) {            System.out.println("请输出一个整数:"); //            inputStr = scanner.next();            try {                num = Integer.parseInt(inputStr); //这里是可能抛出异样                break;            } catch (NumberFormatException e) {                System.out.println("你输出的不是一个整数:");            }        }        System.out.println("你输出的值是=" + num);    }}

throws 异样解决

根本介绍

1) 如果一个办法(中的语句执行时)可能生成某种异样,然而并不能确定如何解决这种异样,则此办法应显示地申明抛出异样,表明该办法将不对这些异样进行解决,而由该办法的调用者负责解决
2) 在办法申明中用throws语句能够申明抛出异样的列表,throws前面的异样类型能够是办法中产生的异样类型,也能够是它的父类。

疾速入门案例

throws前面的异样类型能够是办法中产生的异样类型(也能够是异样列表,抛出多个异样),也能够是它的父类(例如 Exception)。

package com.hspedu.throws_;import java.io.FileInputStream;import java.io.FileNotFoundException;public class Throws01 {    public static void main(String[] args) {    }    public void f2() throws FileNotFoundException,NullPointerException,ArithmeticException {        //创立了一个文件流对象        //1. 这里的异样是一个FileNotFoundException 编译异样        //2. 应用后面讲过的 try-catch-finally        //3. 应用throws ,抛出异样, 让调用f2办法的调用者(办法)解决        //4. throws前面的异样类型能够是办法中产生的异样类型,也能够是它的父类(例如 Exception)        //5. throws 关键字后也能够是 异样列表, 即能够抛出多个异样        FileInputStream fis = new FileInputStream("d://aa.txt");    }}

注意事项和应用细节

  1. 对于编译异样,程序中必须解决,比方try-catch或者throws。
  2. 对于运行时异样,程序中如果没有解决,默认就是throws的形式解决(相当于办法后有一个throws XXXException,这时逐级向上,最初main办法上可能也默认throws,这时就给JVM解决)。
  3. 子类重写父类的办法时,对抛出异样的规定:子类重写的办法,所抛出的异样类型要么和父类抛出的异样统一,要么为父类抛出的异样的类型的子类型。
  4. 在throws过程中,如果有办法 try-catch,就相当于解决异样,就能够不用 throws。

    例如子类有一个编译异样,应用throws抛出,那么父类也必须对该异样做出反馈,或是throws,或者try catch,否则同样是编译异样。

自定义异样

基本概念

当程序中呈现了某些“谬误”,但该错误信息并没有在 Throwable 子类中形容解决,这个时候能够本人设计异样类,用于形容该错误信息。

自定义异样的步骤

1) 定义类:自定义异样类名(程序员本人写)继承Exception或RuntimeException

  • 如果继承Exception,属于编译异样
  • 如果继承RuntimeException,属于运行异样(一般来说,继承RuntimeException)

自定义异样的利用实例

当咱们接管Person对象年龄时,要求范畴在18-120之间,否则抛出一个自定义异样(要求继承RuntimeException),并给出提示信息。

package com.hspedu.customexception_;public class CustomException {    // 办法申明处,throws 异样    public static void main(String[] args) /*throws AgeException*/ {        int age = 180;        //要求范畴在 18 – 120 之间,否则抛出一个自定义异样        if(!(age >= 18 && age <= 120)) {            //这里咱们能够通过结构器,设置信息            // 在办法体中,这里 throw 对象            throw new AgeException("年龄须要在 18~120之间");        }        System.out.println("你的年龄范畴正确.");    }}// 自定义一个异样// 1. 个别状况下,咱们自定义异样是继承 RuntimeException// 2. 即把自定义异样做成 运行时异样,益处是咱们能够应用默认的解决机制,即主动向上throws异样,否则main中也得加throws。class AgeException extends RuntimeException {    public AgeException(String message) {//结构器        super(message); // 调用父结构器,能够进入源码逐级查看。    }}

父结构器:

    public Throwable(String message) {        fillInStackTrace();        detailMessage = message; // 传入 detailmessage    }

throw 和 throws 的区别

练习

编程题

编写应用程序,接管命令行的两个参数(整数),计算两数相除。

计算两个数相除,要求应用办法 cal(int n1, int n2)

对数据格式不正确(NumberFormatException)、短少命令行参数(ArrayIndexOutOfBoundsException)、除0 进行异样解决(ArithmeticException)。

package com.hspedu.homework;public class Homework01 {    public static void main(String[] args) {        /*        编写应用程序EcmDef.java,接管命令行的两个参数(整数),计算两数相除。        计算两个数相除,要求应用办法 cal(int n1, int n2)        对数据格式不正确(NumberFormatException)、短少命令行参数(ArrayIndexOutOfBoundsException)、除0 进行异样解决(ArithmeticException)。         */        try {            //先验证输出的参数的个数是否正确 两个参数            if(args.length != 2) {                throw new ArrayIndexOutOfBoundsException("参数个数不对");            }            //先把接管到的参数,转成整数            int n1 = Integer.parseInt(args[0]);            int n2 = Integer.parseInt(args[1]);            double res = cal(n1, n2);//该办法可能抛出ArithmeticException            System.out.println("计算结果是=" + res);        } catch (ArrayIndexOutOfBoundsException e) {            System.out.println(e.getMessage());        } catch (NumberFormatException e) {            System.out.println("参数格局不正确,须要输入整数");        } catch (ArithmeticException e) {            System.out.println("呈现了除0的异样");        }    }    //编写cal办法,就是两个数的商    public static double cal(int n1, int n2) {        return n1 / n2;    }}

文章和代码曾经归档至【Github仓库:https://github.com/timerring/java-tutorial 】或者公众号【AIShareLab】回复 java 也可获取。