1、 异常
异常发生时的顺序:
以如下代码为例:
try代码块中执行的为有可能抛出异常的代码,Ibanez异常会出现三种情况:
第一种情况:如果try代码块执行顺利,没有抛出异常,那么以下代码的执行顺序为:
2、3、6、7、8、9、16
第二种情况:如果try代码块出现抛出异常,如第9行抛出算数异常,并且此异常被catch捕获,那么我们执行的顺序为:
2、3、6、7、8、9(抛出算数异常)、10(进入catch代码块)、12、13、14、(catch代码块执行完毕,之后,或据徐执行之后的代码)16
第三种情况:try代码块抛出了异常,不过这个异常没有属于catch的捕获范围,如果我们在第6行抛出一个输入不匹配异常,那么就不会被ctach块捕获,因为我们只捕获了算数异常
2、3、6(抛出输入不匹配)、10、(发现没有捕获这个异常)(此时程序结束,不会进入16行代码)
public static void main(String[] args){
Scanner in=new Scanner(System.in);
System.out.print("请输入被除数:");
try{
//尝试代码,看看会不会出现异常
int num1=in.nextInt();
System.out.print("请输入除数:");
int num2=in.nextInt();
System.out.prinln(num1+"/"+num2+"="+(num1/num2));
}catch (ArithmeticException e){
//成功捕获异常
System.out.print("我抓住异常了!!!"); System.out.print("异常的内容为:"); e.printStackTrace(); } System.out.print("感谢使用本程序!"); }
2、 打印异常内容
打印异常内容有两种方法
public static void main(String[] args){
try{
int i=1/0;
}catch (ArithmeticException e){
//成功捕获异常
System.err.println("我抓住异常了!");
System.err.println("异常内容为:");
//第一种方法
//这种方法会将所有的报错顺序执行打印
System.err.println("第一种方法:");
e.printStackTrace();
//第二种方法
//此方法,只会将错误的信息打印,不会打印具体的报错行号
System.err.println("第二种方法:");
System.err.println(e.getMessage());
}
System.err.println("感谢使用本程序!");
}
3、 fianlly关键字
如下代码:我们在try-catch块之后增加finally代码块,之一段代码块会将在之前提到的三种情况中都会执行。
public static void main(String[] args){
Scanner in =new Scanner(System.in);
System.out.print("请输入被除数:") ;
try{
//尝试代码,看看会不会出现异常
int num1=in.nextInt();
System.out.print("请输入除数:");
int num2=in.nextInt();
System.out.println(num1+"/"+num2+"="+(num1/num2));
}catch (ArithmeticException e){
//成功捕获异常
System.out.print("我抓住异常了!!!");
System.out.print("异常的内容为:");
e.printStackTrace();
}finally{
System.out.print("无论代码怎么样,我们都或执行!");
}
System.err.println("感谢使用本程序!")
}
4、 多重catch块
对于try-racth块,我们可以存在多个catch,不同的catch可以捕获不同的异常,所有的异常自上而下进行匹配,如果匹配到了,救进入该catch块执行对应的逻辑;
由于我们提到了多重catch块是为了解决针对不同的异常采取不同的措施,所以catch块中的异常理论应该是不同的逻辑代码。如果你执行的逻辑是相同的。并且,被捕获的类存在父子关系,你只需要写父类的catch,子类的不需要写,因为匹配异常,子类也会被父类类型匹配上。
如果你需要针对不同的异常做出不同的处理,那么你将catch块顺序进行排序,将最大的父类放最后,最小的子类放最上面。
package com.kgc.day14;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Text05{
public static void main(String[] args){
int flag=0;
Scanner in =new Scanner(System.in);
System.out.print("请输入被除数:") ;
try{
//尝试代码,看看会不会出现异常
int num1=in.nextInt();
System.out.print("请输入除数:");
int num2=in.nextInt();
System.out.prinln(num1+"/"+num2+"="+(num1/num2));
}catch(ArithmeticException e){
//成功捕获异常
System.out.print("我抓住异常了!!!1");
System.out.print("异常的内容为:");
e.printStackTrace();
flag++;
}catch(InputMismatchException e){
//成功捕获异常
System.out.print("我抓住异常了!!!2");
System.out.print("异常的内容为:");
e.printStackTrace();
flag++;
}catch(Exception e){
//成功捕获异常
System.out.print("我抓住异常了!!!3");
System.out.print("异常的内容为:");
e.printStackTrace();
flag++;
}finally{
System.out.print("无论代码怎么样,我们都或执行!");
}
System.err.println("感谢使用本程序!") ;
System.err.println("发现异常情况:"+flag) ;
}
}
5、try-ctach-finally存在return情况
public static void main(String[] args){
A a = new A();
ml(a);
System.out.println(a.i);
int i=0;
i=m2(i);
System.out.println(i);
}
//注意此方法传递为基本数据类,基本数据类型传递,传递值
public static int m2(int i){
try{
i++;
return i;
}finally{
i++;
}
}
//注意此方法传递为引用数据类型,引用数据类型传递,传递地址
public static int m1(A a){
try{
a.i++;
return;
}finally{
a.i++;
}
}
6、throws关键字
方法中可以使用throws关键字抛出所有可能发生的异常,并且不去在当前方法处理。交由调用该方法的方法处理这个异常。
我们也可以在main方法中抛出异常,不过这样抛出异常是没有任何意义的,因为没有方法会调用这个方法。
public static void main(String[] args){
try{
m2();
}catch(Exception e){
e.printStackTrace();
}
System.err.println(12312);
}
private static void m2() throws ArithmeticException,NullPointerExcept{
m1();
}
public static void m1() throws ArithmeticException,NullPointerExcept{
int i=1/0;
}
7、throw关键字
throw和throws完全是两个概念,throws是将已经发生的异常进行抛出处理,而throw关键字用于抛出一个新发生的异常。
public static void main(String[] args){
try{
m1(1);
}catch(Exception e){
e.printStackTrace();
}
}
public static void m1(int i)throws Exception{
if(i==1){
throws new Exception("这里参数不能为1,为1抛异常");
}else{
System.err.println("你的参数不是1");
}
}
java.lang.Excrption:这里参数不能那为1,为1抛异常
at com.kgc.day14.Test08.m1(Test08.java:15)
at com.kgc.day14.Test08.main(Test08.java:7)
8、 RuntimeExcption和CheckedException的区别
一般我们将非继承RuntimeException的异常(直接继承Exception的异常类)称之为CheckedException。之所以叫检查异常,是因为他们在编写的时候就会进行检查。
什么叫编译的时候就会进行检查:当我们的代码编写的时候会进行检查,如果这里发生异常(非RuntimeException子类的异常)的时候,我们必须要处理,处理可以选择throws抛出给别人处理,或者自己直接try-catch处理。
9、 自定义异常
根据情况,我们可以选择将我们的自定义异常声明成为要给checkedException或者RuntimeException,选择那种情况,完全取决于你的业务场景。
public class HappyException extends Exception{
public HappyException(String[] message){
super(message);
}
}
public static void main(String[] args){
try{
m1();
}catch(HappyException e){
e.printStackTrance();
System.out.println("123:"+e.getMessage());
System.out.println("你是不是输入了不该输入的字符串?");
}
System.out.println("后面的代码....");
}
public static void m1() throws HappyException{
Scanner in =new Scanner(System.in);
System.out.println("请输入一个状态,不能输入Happy");
String str=input.next();
if("Happy".equal(str)){
throws new HappyException("这里不能输入Happy123")
}
}