0
点赞
收藏
分享

微信扫一扫

java笔记,异常机制(记录java从入门到入土)

单调先生 2022-02-13 阅读 97

目录

目标:

什么是异常:

为什么要用try{}catch(){}:

try{}catch(){}的执行原理:

Finally:

异常体系结构:

java中分为两大类异常:RuntimeException,运行时异常,非受检异常。和受检异常。

一个简单的异常:

异常处理演示try{}catch(){}:

再演示一个简单的异常:

多异常处理的三种格式:

1.通过多个catch完成:

2.通过|符号:

3.使用里氏代换原则,更大范围的异常来捕获

异常的抛出:

造出一个异常并将异常抛出Exception 受检异常,制造异常时必须抛出让调用者处理:

造出一个异常并将异常抛出RuntimeException 非受检异常,制造异常时可以不抛出,让调用者使用时处理:

面试题代码:

try-catch-finally中,如果catch中return了,finally会执行吗:finally中的代码会执行。

try-catch-finally中,都有return代码,以谁的为最终返回值:finally

在没有异常的情况下,对变量进行改变:

在没有异常的情况下,对对象进行改变:

面试题:

自定义异常:


目标:

1.明确什么是异常。(重点)

2.能辨别出常见的异常及其含义。(熟悉)

3.理解异常对象产生的原理。(了解)当异常出现了,java把它变成一个对象,里边包含所有不对劲情况的信息,jvm将不对劲的信息封装成对象。

4.能处理异常。(重点)

5.能够自定义异常类型。(熟悉)

什么是异常:

程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行。

为什么要用try{}catch(){}:

用while()循环用if()判断一样可以处理异常,为什么一定要中try{}catch(){},因为这个时java官方所提供的规则,规范。用这种统一的规则可以放代码更容易阅读。且保持代码的清晰。

try{}catch(){}的执行原理:

1.一旦产生异常,则系统会产生一个异常类的实例化对象,如果产生的异常是ArrayIndexOutOfBoundsException,则会产生一个ArrayIndexOutOfBoundsException类型的对象。这个对象需要被处理需要被抓到,如果不处理,程序崩溃。

2.如果异常发生在try块里边,则会自动找到匹配的catch块语句去执行,如果没有在try块中,则会将异常抛出。

3.所有的catch块会根据参数匹配异常类的实例化对象,如果catch块类型和产生的类型一致,则catch进行处理。

Finally:

异常的统一出口,如果在try块中有1-7行代码,第3行代码出现异常,则4567行不会再执行,因为第3行代码出现异常会直接跳到相应的catch块去处理,处理完之后代码往下走不会再调回执行4567行。无论是否发生异常,finally里的代码都会作为trycatch语句块最后的收尾代码,一定会在最后执行。

int[] arr = {1, 2};

for (int i = 0; i <= arr.length; i++) {

try {

System.out.print(arr[i]);

//System.out.print(10 / 0);

System.out.println("不执行");

} catch (ArrayIndexOutOfBoundsException|ArithmeticException e) {

System.out.println("发生问题是一套处理方案");

}finally {

System.out.println("执行");

}

}

1不执行

执行

2不执行

执行

发生问题是一套处理方案

执行

异常体系结构:

 

java中分为两大类异常:RuntimeException,运行时异常,非受检异常。和受检异常。

一个简单的异常:

//简单的除法计算器

Scanner input = new Scanner(System.in);

在算数上除数不能为0

//如果除数为0则出现ArithmeticException异常,算数异常

System.out.println("请输入被除数:");

int x = input.nextInt();

System.out.println("请输入除数:");

int y = input.nextInt();

//传统处理方法

//运用while解决异常

while (y==0){

System.out.println("除数不能为0");

System.out.println("请重新输入除数:");

y = input.nextInt();

}

int z = x / y;

System.out.println("两数相除的结果是:" + z);

}

异常处理演示try{}catch(){}:

/**

* try {

* 捕获语句块

* }catch(异常类型 异常对象){

* }

* 按照这种方式可以保证程序不被中断,如果代码发生异常没有去处理,就会导致程序中断

*/

//简单的除法计算器

Scanner input = new Scanner(System.in);

//如果除数为0则出现ArithmeticException异常

System.out.println("请输入被除数:");

int x = input.nextInt();

System.out.println("请输入除数:");

int y = input.nextInt();

int z = 0;

try {

//如果除数为0则出现ArithmeticException异常

z = x / y;

} catch (ArithmeticException e) {

//这里代码一旦执行,24行一定发生异常

System.out.println("出现了异常");

}

System.out.println("两数相除的结果是:" + z);

再演示一个简单的异常:

/**

* 捕获异常,必须捕获的异常类型和发生的异常是匹配的才能被捕获到

* ArrayIndexOutOfBoundsException:数据下标越界异常

*/

int[] arr = {1, 2, 3, 4, 5};

for (int i = 0; i <= arr.length; i++) {

try{

System.out.print(arr[i]);

}catch (ArrayIndexOutOfBoundsException e){

System.out.println("数组下标越界异常");

//捕获异常,必须捕获的异常类型和发生的异常是匹配的才能被捕获到

}/*catch (ArithmeticException e){

System.out.println("数组下标越界异常");

}*/

}

多异常处理的三种格式:

1.通过多个catch完成:

try{}catch(){}catch(){}...

int[] arr = {1, 2, 3, 4, 5};

for (int i = 0; i <= arr.length; i++) {

try {

System.out.print(arr[i]);

System.out.print(10 / 0);

} catch (ArrayIndexOutOfBoundsException e) {

System.out.println("数组下标越界异常");

//捕获异常,必须捕获的异常类型和发生的异常是匹配的才能被捕获到

} catch (ArithmeticException e) {

System.out.println("算数异常");

}

}

2.通过|符号:

try{}catch(类型1|类型2 对象名){}

int[] arr = {1, 2, 3, 4, 5};

for (int i = 0; i <= arr.length; i++) {

try {

System.out.print(arr[i]);

System.out.print(10 / 0);

} catch (ArrayIndexOutOfBoundsException|ArithmeticException e) {

System.out.println("发生问题是一套处理方案");

}

}

3.使用里氏代换原则,更大范围的异常来捕获

* 异常是有范围的概念的,有些异常之间是包含关系的,一种类型的异常的下边会分成好几十种不同的子类异常。

* 如果捕获的是更大范围的,可以用更大范围的异常类型去抓取。

int[] arr = {1, 2};

for (int i = 0; i <= arr.length; i++) {

try {

System.out.print(arr[i]);

//System.out.print(10 / 0);

System.out.println("不执行");

} catch (RuntimeException e) {

System.out.println("发生问题是一套处理方案");

}

}

异常的抛出:

int z = 0;

try {

z = haha(10, 0);

} catch (Exception e) {

//e.printStackTrace();

System.out.println("出现异常");

}

System.out.println(z);

}

/**

* 除法运算

* throws将异常抛给调用者

* ArithmeticException属于运行时异常,写出的代码不漂红

* Exception属于异常的大类,调用时代码飘红

*/

public static int haha(int x, int y) throws Exception {

return x / y;

}

造出一个异常并将异常抛出Exception 受检异常,制造异常时必须抛出让调用者处理:

Person p = new Person();

try {

p.setAge(-18);//当调用时会飘红,必须处理

} catch (Exception e) {

System.out.println("异常");

}

}

static class Person {

private String name;

private int age;

@Override

public String toString() {

return "Person{" +

"name='" + name + '\'' +

", age=" + age +

'}';

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) throws Exception {

if (age < 0) {

//制造一个异常

Exception e = new Exception("年龄异常");

//这行代码就是异常,因为Exception是受检异常异常要不throws要不自己处理

throw e;

}

this.age = age;

}

造出一个异常并将异常抛出RuntimeException 非受检异常,制造异常时可以不抛出,让调用者使用时处理:

Person2 p = new Person2();

p.setAge(-18);//调用时不会飘红,运行时会出现异常

}

static class Person2 {

private String name;

private int age;

@Override

public String toString() {

return "Person{" +

"name='" + name + '\'' +

", age=" + age +

'}';

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age){

if (age < 0) {

//制造一个异常

RuntimeException e = new RuntimeException("年龄异常");

//这行代码就是异常,因为是运行时异常,调用时运行才出现异常

throw e;

}

this.age = age;

}

面试题代码:

try-catch-finally中,如果catch中return了,finally会执行吗:finally中的代码会执行。

public static void main(String[] args) {

System.out.println(test1());//执行完finally里的打印,返回test1里的值

}

public static int test1() {

//在try块中return,有可能执行不到return遇到异常就进入catch了,catch没有return最终是没有返回值,所以要给一个返回值

try {

return 1;

} catch (Exception e) {

e.printStackTrace();

} finally {

System.out.println("zzzzz");

}

return 0;

}

try-catch-finally中,都有return代码,以谁的为最终返回值:finally

public static void main(String[] args) {

System.out.println(test1());//return 2

}

public static int test1() {

try {

return 1;

} catch (Exception e) {

e.printStackTrace();

} finally {

System.out.println("zzzzz");

return 2;

}

在没有异常的情况下,对变量进行改变:

System.out.println(test1());//return 1

//因为int是基本数据类型,在返回的时候x的内容就是1,把1准备好了return,finally把x改为2,不影响已经准备好return的1

int x=1,在return的时候有一个返回值,临时变量用t接收,t=x,将1作为返回值备份了,无论finally怎么改变x的值,之前备份过了,不会改变备份的x的值。

}

public static int test1() {

int x = 0;

try {

x = 1;

return x;

} catch (Exception e) {

e.printStackTrace();

} finally {

x = 2;

}

return x;

}

在没有异常的情况下,对对象进行改变:

System.out.println(test1().getAge());// 2

//引用数据类型准备返回的是堆内存的地址。

//new一个对象,在return的时候有一个返回值,临时变量用t接收,t=s,则s,t都指向了同一个内存地址。

//当finally怎么改变s.age的值,之前备份过的是内存地址,则会改变

}

public static Student test1() {

Student s = new Student();

try {

s.age = 1;

return s;

} catch (Exception e) {

e.printStackTrace();

} finally {

s.age = 2;

}

return s;

}

static class Student {

int age;

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

面试题:

1.try catch finally能省略哪些:finally块可以省略,catch也可以省略,但是try catch组合没有意义。catch和finally可以省略其中一个。

2.try-catch-finally中,如果catch中return了,finally会执行吗:finally中的代码会执行。

3.try-catch-finally中,都有return代码,以谁的为最终返回值:finally。

4.如果try或者catch通过System.exit(0)退出程序,finally还会执行吗:不执行,退出jvm虚拟机了不会执行finally块。

5.写出5个常见的异常类型:ArrayIndexOutOfBoundsException(数组下标越界异常),ArithmeticException(算数异常),NullPointerException(空指针异常)

自定义异常:

//如果想要异常在编写代码时就报错继承Exception

//如果想要异常在运行时出错提示就继承RuntimeException

public class AgeExption extends Exception {

public AgeExption() {

this("年龄异常");

}

public AgeExption(String message) {

super(message);

}

}

/**

*

* @param age

* @throws AgeExption 年龄异常不能小于0大于190

*/

public void setAge(int age) throws AgeExption {

if (age < 0 || age > 190) {

AgeExption ageExption = new AgeExption();

throw ageExption;

}

this.age = age;

}

举报

相关推荐

0 条评论