Day12_异常相关


java-异常查询表

一. 异常的概念

什么是异常

程序在运行过程中出现的非正常的情况,最终会导致JVM的非正常停止。

在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象。Java处理异常的方式是中断处理。

异常指的并不是语法错误,语法错了,编译不通过,不会产生字节码文件,根本不能运行.

二. Throwable体系

  • Throwable:可抛出的,一切错误或异常的父类,位于java.lang包中。
    • |-Error:JVM、硬件、执行逻辑错误,不能手动处理。只能事先避免。
    • |-Exception:程序在运行和配置中产生的问题,可处理。
      • |-RuntimeException:运行时异常,可处理,可不处理。
      • |-CheckedException:编译时异常(受查异常),必须处理。
public class Test1 {
	public static void main(String[] args) {
        test();	// error
	}
	public static void test() {
		String string= "";
		string += string;
		test();
	}
}

Exception in thread “main” java.lang.StackOverflowError

public class Test2 {
	public static void main(String[] args) {
		Integer.parseInt("abc");//Exception
	}
}

Exception in thread “main” java.lang.NumberFormatException: For input string: “abc”

public class Test3 {
	public static String tempString;
	public static void main(String[] args) {
		System.out.println(tempString.equals("")); 
	}
}

Exception in thread “main” java.lang.NullPointerException

public class Test4 {
	public static void main(String[] args) {
		String[] string = new String[10];	// java.lang.ArrayIndexOutOfBoundsException
		for (int i = 0; i <= string.length; i++) {
			System.out.println(string[i]);
		}
	}
}

Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: 10
在这里插入图片描述
在这里插入图片描述
受查异常

三. 异常的产生

自动抛出异常:

当程序在运行是遇到不符合规范的代码或结果时,会产生异常。

在这里插入图片描述

手动抛出异常:throw

语法:

throw new 异常类型("实际参数");

throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行

【注】

  • throw关键字必须写在方法内。
  • throw关键字后面new的对象必须是Exception或Exception的子类对象
  • throw关键字抛出的异常对象
    • 如果是RuntimeException或其子类对象,则可以不处理;
    • 如果不是,则必须处理。
      • 一种是进行捕获处理。try…catch…
      • 另一种就是使用throws继续将问题声明出去。

四. 异常的传递

异常的传递:按照方法的调用链反向传递,如始终没有处理异常,最终会由JVM进行默认 异常处理(打印堆栈跟踪信息)。 e.printStackTrace();

受查异常throws 声明异常,修饰在方法参数列表后端。用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常)。

格式:

修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2{   }

【注】:

  • 编译时异常有两种处理方案:try…catch …或者 throws,如果采用 throws 这种方案,将来谁调用谁处理
  • 运行时异常可以不处理,出现问题后,需要我们回来修改代码

运行时异常:因可处理可不处理,无需声明异常。

【例】:异常的传递 & throws

public class Test1 {
	public static void main(String[] args) {
		t1();
	}
	public static void t1() {
		t2();
	}
	public static void t2() {
		t3();
	}
	public static void t3() {
		Integer.parseInt("abc");
	}
}

在这里插入图片描述


public class Test1 {
	public static void main(String[] args) {
		try {
			t1();
		} catch (Exception e) {
			System.out.println("有问题...");
//			e.printStackTrace();
		}
        System.out.println("// 继续执行下面的代码");
	}
	public static void t1() throws Exception {
		t2();
	}
	public static void t2() throws Exception {
		t3();
	}
	public static void t3() throws Exception {
		Integer.parseInt("abc");
	}
}
image-20200813154120836

五. 异常的处理

关键字

Java异常处理的五个关键字:try、catch、finally、throw、throws

try…catch…(finally…)结构
try {
    可能出现异常的代码
} catch(Exception e) {
    异常处理的相关代码
    // 如:getMessage()、printStackTrace()、toString()
} finally {
    无论是否出现异常,都需执行的代码结构
    // 常用于释放资源。
}

执行流程:

  • 程序从 try 里面的代码开始执行
  • 出现异常,就会跳转到对应的 catch 里面去执行
  • 执行完毕之后,程序还可以继续往下执行

【注】

  • try和catch都不能单独使用,必须连用。
  • finally不能单独使用。必须和try一起使用
  • 如果finally有return语句,永远返回finally中的结果,尽量避免该情况。(详见【附例1】)
  • 父类异常什么样,子类异常就什么样。(详见【附例2】)
    • 如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常。
    • 父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出

【附例1】

public class Demo01 {
    public static void main(String[] args) {
        int a = getA();
        System.out.println(" a = " + a);
    }
    public static int getA() {
        int a = 10;
        try {
            return a;
        } catch (Exception e) {
            System.out.println(e);
        } finally {
            a = 100;
            return a;
        }
    }
}

运行结果:

a = 100

【附例2】

public class Super {
    public void show01() throws NullPointerException,ClassCastException{}
    public void show02() throws IndexOutOfBoundsException{}
    public void show03() throws IndexOutOfBoundsException{}
    public void show04() throws Exception {}
}

class Sub extends Super{
    //子类重写父类方法时,抛出和父类相同的异常
    public void show01() throws NullPointerException,ClassCastException{}
    //子类重写父类方法时,抛出父类异常的子类
    public void show02() throws ArrayIndexOutOfBoundsException{}
    //子类重写父类方法时,不抛出异常
    public void show03() {}

    /*
        父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。

     */
    //public void show04() throws Exception{}

    //此时子类产生该异常,只能捕获处理,不能声明抛出
    public void show04()  {
        try {
            throw new Exception("编译期异常");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
常见的异常处理结构
try {} catch {}
try {} catch {} catch {}
try {} catch {} finally {}
try {} catch {} catch {} finally {}
try {} finally {}

【注】:多重catch,遵循从子(小)到父(大)的顺序,父类异常在最后。

【快捷键】:Alt + Shift + Z

throws和throw的区别

throws

  • 用在方法声明后面,跟的是异常类名
  • 表示抛出异常,由该方法的调用者来处理
  • 表示出现的一种可能性,并不一定会发生这些异常

throw

  • 用在方法体内,跟的是异常对象名
  • 表示抛出异常,由方法体内的语句处理
  • 执行throw 一定抛出了某种异常
【例】:getMessage()、printStackTrace()、toString()的不同
public class ExceptionDemo02 {
    public static void main(String[] args) {
        System.out.println("开始");
        method();
        System.out.println("结束");
    }

    public static void method() {
        try {
            int[] arr = {1, 2, 3};
            System.out.println(arr[3]); //new ArrayIndexOutOfBoundsException();
            System.out.println("这里能够访问到吗");
        } catch (ArrayIndexOutOfBoundsException e) { //new ArrayIndexOutOfBoundsException();
            //System.out.println("调用e.printStackTrace()");	// 方法一
	        //e.printStackTrace();	// public void printStackTrace():把异常的错误信息输出在控制台
            //=========================================================
            //System.out.println("调用e.getMessage()");		// 方法二 
	        //System.out.println(e.getMessage());	// public String getMessage():返回此 throwable 的详细消息字符串
            //=========================================================
            //System.out.println("调用e.toString()");		// 方法三
	        //System.out.println(e.toString());	// public String toString():返回此可抛出的简短描述
            //=========================================================
        }
    }
}

六. 自定义异常

在开发中总是有些异常情况是JDK内部没有定义好的,例如年龄负数问题,考试成绩负数问题等等。因此需要根据自己业务的情况来自定义异常类。

概念:需继承Exception或Exception的子类,代表特定问题。

经验:异常类型名称望文生义,可在发生特定问题时抛出对应的异常。

常用构造方法:
  • 无参构造方法
  • String message参数的构造方法
方法重写
  • 方法名、参数列表、返回值类型必须和父类相同。
  • 子类的访问修饰符和父类相同或比父类更宽。
  • 子类中的方法,不能抛出比父类更多、更宽的异常
【例】:自定义异常

自定义异常类

public class ScoreException extends Exception {

    public ScoreException() {}

    public ScoreException(String message) {
        super(message);
    }

}

老师类

public class Teacher {
    public void checkScore(int score) throws ScoreException {
        if(score<0 || score>100) {
//            throw new ScoreException();
            throw new ScoreException("你给的分数有误,分数应该在0-100之间");
        } else {
            System.out.println("成绩正常");
        }
    }
}

测试类

public class Demo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入分数:");

        int score = sc.nextInt();

        Teacher t = new Teacher();
        try {
            t.checkScore(score);
        } catch (ScoreException e) {
            e.printStackTrace();
        }
    }
}

总结

  • 异常的概念
    • 程序在运行过程中出现的特殊情况。
  • 异常的分类
    • RuntimeException:运行时异常,可处理,可不处理。
    • CheckedException:受查异常,必须处理。
  • 异常的产生
    • throw new 异常类型(“实际参数”);
    • 相当于遇到return语句,导致程序因异常而终止。
  • 异常的传递
    • 按照方法的调用链反向传递,如始终没有处理异常,最终会由JVM进行默认异常处理(打印堆栈跟踪信息)。
  • 异常的处理
    • try {} catch {} finally {}
  • 带有异常声明的方法重写
    • 子类中的方法,不能抛出比父类更多、更宽的异常。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值