java异常 常见异常介绍 异常处理 自定义异常 throw和throws的区别 throws作用 意义

一、异常机制介绍

1.可以先通过一段代码来了解异常

int num1 = 10;
int num2 = 0;
int res = num1 / num2;

当执行到第三行时,程序就会出现(抛出)异常 ArithmeticException 当抛出异常后,程序就退出,崩溃了 , 下面的代码就不在执行,java中提供了异常处理机制(如果对异常进行处理,即使出现异常后面的程序也能继续执行)

try { 
       int res = num1 / num2; 
} catch (Exception e) { 
       System.out.println("出现异常的原因=" + e.getMessage());//输出异常信息
}
System.out.println("程序继续运行....");

代码输出如下:

出现异常的原因=/ by zero
程序继续运行...

从这里我们可以对异常机制有个简单的了解:就是防止一些代码异常影响整个代码

二.异常体系图

1. 分析:Exception(异常)分两类runtimeexception(运行时异常)和编译异常

运行时异常主要有以下:

1) NullPointerException 空指针异常
2) ArithmeticException 数学运算异常
3) ArrayIndexOutOfBoundsException 数组下标越界异常
4) ClassCastException 类型转换异常
5) NumberFormatException 数字格式不正确异常 []
总结:
运行时异常,编译器检查不出来。一般是编程时的逻辑错误,可以不做处理。而编译时异常,是编译器要求必须处理的异常。
2.常见运行时异常举例:
1) NullPointerException 空指针异常
String name = null; 
System.out.println(name.length());///抛出NullPointerException

2) ArithmeticException 数学运算异常
                10 / 0
3) ArrayIndexOutOfBoundsException 数组下标越界异常
int[] arr = {1,2,4}; 
for (int i = 0; i <= arr.length; i++) {
     System.out.println(arr[i]);
}

4) 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 {}

5) NumberFormatException 数字格式不正确异常 []
String name = "哈哈"; //将 String 转成 int 
int num = Integer.parseInt(name);//抛出 NumberFormatException

三.异常处理

异常处理的方式:

1 try-catch-finally

(程序员在代码中捕捉发生的异常,自行处理)

try
捕获异常的第一步是用try{…}语句块选定捕获异常的范围, 将可能出现异常的代码放在try语句块中。在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此对象的类型,去catch中进行匹配。 一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常处理,一旦处理完成就跳出当前的try-catch结构(在没有写finally的情况下)。继续执行其后的代码。在try结构中声明的变量,出了try结构之后,就不能被调用。

catch (Exceptiontype e)
在catch语句块中是对异常对象进行处理的代码。 每个try语句块可以伴随一个或多个catch语句, 用于处理可能产生的不同类型的异常对象。catch中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下无所谓,如果异常类型满足子父类的关系,则要求子类一定要声明在父类的上面,否则报错。

finally
捕获异常的最后一步是通过finally语句为异常处理提供一个统一的出口,使得在控制流转到程序的其它部分以前,能够对程序的状态作统一的管理。
不论在try代码块中是否发生了异常事件, catch语句是否执行, catch语句是否有异常, catch语句中是否有return,finally块中的语句都会被执行。
finaly中声明的是一定会被执行的代码,即使catch中出现了异常,try中有return语句,catch中有return语句等情况。

例子:

单个异常:最开始的例子

多个异常:

public static void main(String[] args) {
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; 
    } 
}

总结:

 4)当有多个异常时,子类异常写在前面;

2.throws

(将发生的异常抛出,交给调用者处理,最顶级的处理着是JVM)

如果一个方法(中的语句执行时)可能生成某种异常, 但是并不能确定如何处理这种异常, 则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。
在方法声明中用throws语句可以声明抛出异常的列表, throws后面的异常类型可以是方法中产生的异常类型, 也可以是它的父类。
一旦方法体执行时,出现异常,仍会在异常代码处,生成一个异常类的对象,此对象满足throws后异常类型是,就会被抛出。异常代码后续的代码,就不在执行。
throws的方式只是将异常抛给了方法的调用者,并没有真正将异常处理掉。

四、自定义异常

例题:当我们接受一个Person对象年龄时,要求范围在18-200之间,否则抛出一个自定义异常(要求继承RuntimeException),并给出提示信息。

public class CustomException { 
    public static void main(String[] args) /*throws AgeException*/ { 
        int age = 180; //要求范围在 18 – 120 之间,否则抛出一个自定义异常 
        if(!(age >= 18 && age <= 120)) { 
            //这里我们可以通过构造器,设置信息 
            throw new AgeException("年龄需要在 18~120 之间");
        }
    System.out.println("你的年龄范围正确.");
    } 
}
class AgeException extends RuntimeException { 
    public AgeException(String message) {   
    //构造器 
    super(message); //这里的super调用的是RuntimeException父类里的构造器 输出异常信息
    } 
}
//1. 一般情况下,我们自定义异常是继承 RuntimeException
     如果用extends Exception (抛出编译异常)就必须在main函数 throws AgeException
//2. 即把自定义异常做成 运行时异常,好处时,我们可以使用默认的处理机制 
//3. 即比较方便

到这有两个疑问:

1.throws和throw的区别。

 

throw是自己定义的异常,就是说 编程和运行都不会出问题,但是不符合逻辑,就像去取钱。钱被取成负数。不符合逻辑。所以要用throw。

throws是在函数声明的地方写的,表示该函数可能出现的异常,需要调用单位来处理。一般有throw的函数要配合throws使用。

上面的两种都是异常的处理方法之一“抛”,意味着函数异常没有被解决,而是交给上级解决。最终解决需要try和catch来解决

用throw抛出一个异常对象,然后用catch接受。
 

2.throws有什么作用?什么意义?

作用:

当你的方法里抛出了checked异常(编译异常),如你不catch,代表你当时不处理(不想处理或没条件处理),但你必须得通过"throws那个异常"告诉系统说,这儿有个问题,我现在不处理,将来一定别人要处理,否则执行到它,马克-to-win:系统会"不优雅"的崩溃。举个例子,工兵张三发现了地雷,假如他处理,完事就完事儿了。但是他发现了地雷,自己却没带齐工具,没法处理,他必须做个标记,说这儿有一个地雷,别的工兵将来一定要处理,否则将来有人踩上去会爆炸。

注意:throws只是标记,并没处理,执行到那,系统还是会崩溃!

语法总结就是:当你的方法里抛出了checked异常 (编译异常),如你不catch,必须throws,即告诉编译器,我的调用者会处理。如果你已经是main,则main的调用者jvm会替你收拾残局。否则无法编译通过。
意义:
hrows的意义,在于和throw配合起来一起工作。就像这个自定义异常的例题,定义了AgeException异常 在里面throw AgeException,并且在main函数后throws AgeException。又因这题AgeException extends RuntimeException(运行时异常),所以在main函数后 throws RuntimeException 可有可无,但如果extends 编译异常 做必须 throws。
  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值