ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JavaSE之异常分析

2021-12-02 10:04:11  阅读:145  来源: 互联网

标签:分析 System try catch JavaSE 异常 throws out


导航小助手

异常

异常的背景

在先前的编程中就已经接触一些异常

除以0

System.out.println(10 / 0);

Exception in thread “main” java.lang.ArithmeticException: / by zero

数组越界访问

int[] arr = {1, 2, 3};
System.out.println(arr[100]);

Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: 100

空指针异常

public class Test {
	public int num = 10;
	public static void main(String[] args) {
		Test t = null;
		System.out.println(t.num);
	}
}

Exception in thread “main” java.lang.NullPointerException

异常就是在程序运行时出现的错误,与编译时错误要分别开

LBYL&&EAFP

LBYL: Look Before You Leap.
EAFP: It’s Easier to Ask Forgiveness than Permission.

前者在程序执行前解决问题,后者出现问题后解决

异常的好处

下面给出一个例子

LBYL风格

boolean ret = false;
ret = 登陆游戏();
if (!ret) {
	//处理登陆游戏错误;
	return;
}
ret = 开始匹配();
if (!ret) {
	//处理匹配错误;
	return;
}
ret = 游戏确认();
if (!ret) {
	//处理游戏确认错误;
	return;
}
ret = 选择英雄();
if (!ret) {
	//处理选择英雄错误;
	return;
}
ret = 载入游戏画面();
if (!ret) {
	//处理载入游戏错误;
	return;
}
try {
	//登陆游戏();
	//开始匹配();
	//游戏确认();
	//选择英雄();
	//载入游戏画面();
	//...
} catch (登陆游戏异常) {
	//处理登陆游戏异常;
} catch (开始匹配异常) {
	//处理开始匹配异常;
} catch (游戏确认异常) {
	//处理游戏确认异常;
} catch (选择英雄异常) {
	//处理选择英雄异常;
} catch (载入游戏画面异常) {
	//处理载入游戏画面异常;
}

异常的用法

捕获异常

一般通过try catch对异常进行捕捉

try{
    //可能出现异常的部分
}catch(异常类型 异常对象){
    //执行程序
}finally{
    //执行语句
}
/**
*1、try 代码块中放的是可能出现异常的代码.
*2、catch 代码块中放的是出现异常后的处理行为.
*3、finally 代码块中的代码用于处理善后工作, 会在最后执行.
*4、其中 catch 和 finally 都可以根据情况选择加或者不加.
*5、finally语句无条件执行
*/
public class Ex {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        System.out.println("before");
        System.out.println(arr[100]);
        System.out.println("after");
    }
}

Snipaste_2021-11-25_10-46-20

int[] arr = {1, 2, 3};
try {
	System.out.println("before");
	System.out.println(arr[100]);
	System.out.println("after");
} catch (ArrayIndexOutOfBoundsException e) {
// 打印出现异常的调用栈
	e.printStackTrace();
}
System.out.println("after try catch");

Snipaste_2021-11-25_11-21-06

我们发现, 一旦 try 中出现异常, 那么 try 代码块中的程序就不会继续执行, 而是交给 catch 中的代码来执行. catch 执行完毕会继续往下执行.


异常处理

有关异常的处理

1、异常的种类有很多, 我们要根据不同的业务场景来决定.

2、对于比较严重的问题(例如和算钱相关的场景), 应该让程序直接崩溃, 防止造成更严重的后果

3、对于不太严重的问题(大多数场景), 可以记录错误日志, 并通过监控报警程序及时通知程序员

4、对于可能会恢复的问题(和网络相关的场景), 可以尝试进行重试.

5、在我们当前的代码中采取的是经过简化的第二种方式. 我们记录的错误日志是出现异常的方法调用信息, 能很快速的让我们找到出现异常的位置. 以后在实际工作中我们会采取更完备的方式来记录异常信息.

流程

1、程序先执行 try 中的代码

2、如果 try 中的代码出现异常, 就会结束 try 中的代码, 看和 catch 中的异常类型是否匹配.

3、如果找到匹配的异常类型, 就会执行 catch 中的代码

4、如果没有找到匹配的异常类型, 就会将异常向上传递到上层调用者.

5、无论是否找到匹配的异常类型, finally 中的代码都会被执行到(在该方法结束之前执行).

6、如果上层调用者也没有处理的了异常, 就继续向上传递.

一直到 main 方法也没有合适的代码处理异常, 就会交给 JVM 来进行处理, 此时程序就会异常终止.


异常声明

我们在处理异常的时候, 通常希望知道这段代码中究竟会出现哪些可能的异常.

我们可以使用 throws 关键字, 把可能抛出的异常显式的标注在方法定义的位置. 从而提醒调用者要注意捕获这些异常

public static int divide(int x, int y) throws ArithmeticException {
	if (y == 0) {
		throw new ArithmeticException("抛出除 0 异常");
	}
	return x / y;
}

Java异常体系

11

自定义异常

package day1125;

import java.util.Scanner;

class UserError extends Exception {
    public UserError(String message) {
        super(message);
    }
}
class PasswordError extends Exception {
    public PasswordError(String message) {
        super(message);
    }
}
public class Login {
    private static String userName = "admin";
    private static String password = "123456";

    public static void main(String[] args) {
        Scanner scanner =new Scanner(System.in);
        System.out.print("输入用户名>>");
        String name= scanner.nextLine();
        System.out.print("输入密码>>");
        String password=scanner.nextLine();
        try {
            login(name, password);
        } catch (UserError userError) {
            userError.printStackTrace();
        } catch (PasswordError passwordError) {
            passwordError.printStackTrace();
        }
    }
    public static void login(String userName, String password) throws UserError,
            PasswordError {
        if (!Login.userName.equals(userName)) {
            throw new UserError("用户名错误");
        }
        if (!Login.password.equals(password)) {
            throw new PasswordError("密码错误");
        }
        System.out.println("登陆成功");
    }
}


Snipaste_2021-11-25_13-43-20


有关throws和throw

1、位置不同:throws在方法的声明后面,后面跟的是异常类名,而throw在方法的内部,后面跟的是异常的类名

2、抛出数量不同:throws可以抛出多个异常类,用逗号隔开,而throw只能抛出一个异常对象

3、处理方法不同:throws抛出后由该方法的调用者来处理,后者由由该方法体内的语句来处理

4、可能性不同:throws表示有出现异常的可能性,并不一定出现这些异常,throw一定有异常


可以对比上面自定义登录的例子

可以看见throws后面抛出类,throw后面抛出对象

throws抛出账户错误和密码错误两个类,后着抛出一个准确的对象

当账户密码正确throws就不会抛出异常


如有错误欢迎指正

标签:分析,System,try,catch,JavaSE,异常,throws,out
来源: https://blog.csdn.net/wang_fm/article/details/121663926

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有