第2单元 异常处理(Exception)
1.除法计算不用异常
- 直接报错、程序终止执行
public double div(int num1, int num2) {
double result = num1 / num2;
return result;
}
2.除法计算使用异常
- 提示更为友好-程序还能继续
- 处理异常:选中错误语句,alt+ shift+z,回车
public double div(int num1, int num2) {
//局部变量在使用前必须明确赋值
double result = 0;
try {
result = num1 / num2;//JVM会自动创建一个异常类对象ArithmeticException
//new ArithmeticException();
System.out.println("1111");//不执行
} catch (Exception e) {
//e.printStackTrace();
System.out.println("除数不能为0!");
} finally {//不管有无异常,都会执行;可选的,一般用于释放资源
System.out.println("tit cs");
}
return result;
}
(1)【面试题】异常处理机制如何?
- 首先:执行到异常行时,JVM自动创建一个异常类对象(抛出异常);后面的代码不再执行。然后:catch捕获异常,执行catch中的代码。如果catch无法捕获异常,程序会退出。
(2)异常处理语法如何?
- try {} catch {} finally {} ;finally是不管有无异常,都会执行;一般用于释放资源。以下代码返回值300
public int get() {
try {
return 100;
} catch (Exception e) {
return 200;
} finally {
return 300; //300
}
}
3.除数为0时人工抛出异常,使用throw
- 方式:throw + 异常类对象
throw new ArithmeticException();
- 什么时候用?
- 根据编程者的需要,人工抛出异常。
public double div(int num1, int num2) {
double result = 0;
if (num2 == 0) {
throw new ArithmeticException();
} else {
result = num1 / num2;
}
return result;
}
4.调用者处理异常,使用throws
- 本方法有异常了,但自己不处理,可以抛出去,使用关键字throws;
- 注意位置:方法声明处
public void read() throws FileNotFoundException,ArithmeticException {
FileInputStream fs = new FileInputStream("a.txt");
}
面试题:throws和throw有什么区别?
- throw:人工抛出异常,用在方法体里;throws:放在方法声明处。
5.自定义异常类
-
一般继承Exception
-
提供两个构造方法
-
一般用于处理业务异常,比如:余额不足、检车等与系统功能有关的。
-
(1)自定义异常
/** 自定义异常类:取款余额不足时的异常*/
public class AccountExecption extends Exception {
public AccountExecption() {
super();
}
public AccountExecption(String message) {
super(message);
}
public String toString() {
return "账户余额不足!";
}
}
- (2)实现
/**取款方法,余额不足会抛出业务异常 */
public void withDrawMethod() throws AccountException{
int balance = 200;//余额
int withDraw = 500;//取款金额
if (balance < withDraw) {
throw new AccountException("余额不足");
}
}
public static void main(String[] args) {
BankAccount bankAccount = new BankAccount();
try {
bankAccount.withDrawMethod();
} catch (AccountException e) {
//e.printStackTrace();
//System.out.println(e);
System.out.println(e.getMessage());
}
}
6.取款时余额不足,出现异常,将异常信息在控制台提示
- catch块中绝对不要为空
e.printStackTrace();//打印出错详情,显示在控制台上
//在调试程序(开发时候)推荐使用,便于我们快速排错;但是在生产环境下避免使用。
7.取款时余额不足,出现异常,异常信息记录到日志文件
- 解决方案:使用Log4j 1.x或Log4j 2.x
(1) Log4j是什么?
- 分为Log4j 1.x 和 Log4j 2.x,Log4j2.x是官方推荐版本。
http://logging.apache.org/log4j/1.2/download.html
https://logging.apache.org/log4j/2.x/ - 它是开源的、来自Apache的一个第三方组件。http://www.apache.org
(2) Log4j的作用是什么?
- 答:做日志,异常记录日志、软件执行过程跟踪。目的:给维护人员提供便利。
(3) Log4j的基础配置
-
复制jar包并添加到构建路径中;复制log4j(.xml/.properties/.json)文件到src目录下。这个文件叫做log4j配置文件(属性文件)
-
Log4j由三个重要的组件构成:日志等级(优先级)、日志输出目的地、日志信息输出格式
-
日志等级(优先级):OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL;左侧优先级高,右侧优先级低。常用的是:ERROR(错误)、WARN(警告)、INFO(信息)、DEBUG(调试)
https://blog.csdn.net/sinat_30185177/article/details/73550377?tdsourcetag=s_pcqq_aiomsg
(4) 如何使用Log4j 2.x
- 下载官网:https://logging.apache.org/log4j/2.x/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-73uQmnPM-1594346716547)(https://file.moetu.org/images/2020/04/20/log4j19bb6bacc6e31ae81.png)]
- 将下载好之后的两个jar包导入项目中
- 导入两个jar包后,右键点击Build path->Add to build path;然后创建log4j2.xml文件并配置好内容即可
- .xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="error">
<!--定义appender -->
<appenders>
<!--输出控制台的配置 -->
<Console name="Console" target="SYSTEM_OUT">
<!--控制台只输出trace及以上级别的信息(onMatch),其他的直接拒绝(onMismatch),级别由level的值确定 -->
<ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
<!--输出日志的格式 -->
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
</Console>
<!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用 -->
<!--append为true表示消息增加到指定文件中,false表示消息覆盖指定的文件内容,默认值是true -->
<File name="log" fileName="D:\eclipse\logfiles\log4j2.log" append="true">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
</File>
<!--添加过滤器ThresholdFilter,可以有选择的输出某个级别以上的类别 onMatch="ACCEPT" onMismatch="DENY"意思是匹配就接受,否则直接拒绝 -->
<File name="ERROR" fileName="D:\eclipse\logfiles\error.log">
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
</File>
<!--这个会打印出所有的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 -->
<RollingFile name="RollingFile" fileName="D:\eclipse\logfiles\web.log"
filePattern="logs/$${date:yyyy-MM}/web-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
<SizeBasedTriggeringPolicy size="2MB"/>
</RollingFile>
</appenders>
<!--定义logger,只有定义了logger并引入的appender,appender才能生效 -->
<loggers>
<root level="trace">
<appender-ref ref="RollingFile"/>
<appender-ref ref="Console"/>
<appender-ref ref="ERROR" />
<appender-ref ref="log"/>
</root>
</loggers>
</configuration>
- Log4j测试文件
public class Log4jTest {
private static Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
public static void main(String[] args) {
// 记录trace级别的信息
logger.trace("log4j2日志: Trace日志");
// 记录debug级别的信息
logger.debug("log4j2日志: Debug日志");
// 记录info级别的信息
logger.info("log4j2日志: Info日志");
// 记录error级别的信息
logger.error("log4j2日志: Error日志");
}
}
二、理解
1.什么是异常?为什么使用异常(好处)?
- 定义:异常就是程序执行时发生不正常情况,程序无法完成既定功能。
- 原因:代码出现异常,不至于立即崩溃,在catch中可以写“补救”或提示代码;根据异常提示,快速的发现代码中的错误,以便程序的修改和调试。
2.异常处理机制?如何处理异常?
- 首先:执行到异常行时,JVM自动创建一个异常类对象(抛出异常);后面的代码不再执行。然后:catch捕获异常,执行catch中的代码。如果catch无法捕获异常,程序会退出。
- 处理异常:try {} catch {} finally {} ;finally是不管有无异常,都会执行;一般用于释放资源。
3.异常分类?有什么区别?
- 答:分两类:已检查异常(Checked Exception)和未检查异常(UnChecked Exception),也叫做运行时异常RuntimeException。
- 区别:已检查异常在编译时候就能发现;未检查异常执行起来才能发现。
4.面试题:请列举几个常见的异常
- NullPointerException : 空指针异常
- ArithmeticException : 算术计算异常
- NullPointerException:空指针异常
- NumberFormatException: 数字格式异常
- SQLException
- IOException
5.面试题:Exception与Error的区别?
- 它们都是API中的类
- 异常是有外部环境导致或程序员考虑不周引发的,程序员可以处理它
- 错误由外部环境引起的,程序员无法处理;比如:内存耗尽等。
6.面试题:throws和throw有什么区别?
- throw:人工抛出异常,用在方法体里;
- throws:放在方法声明处,由调用者处理异常。
7.重写时异常如何处理?
- 子类可以抛出更多异常,但是这些异常在父类方法上能找到父类。
- 子类可以抛出更少的异常。
8.final、finally、finalize()的区别?
-
final :修饰符(关键字) 如果一个类被声明为final,意味着它不能再派生新的子类,不能作为父类被继承。
-
finally:用于异常处理,必定要执行,一般用于释放资源。
-
finalize:是方法名java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除之前做必要的清理工作。
9.Log4j是什么?有什么作用?
- 它是开源的、来自Apache的一个第三方组件。
- 作用:做日志。
如何处理?
- 子类可以抛出更多异常,但是这些异常在父类方法上能找到父类。
- 子类可以抛出更少的异常。
8.final、finally、finalize()的区别?
-
final :修饰符(关键字) 如果一个类被声明为final,意味着它不能再派生新的子类,不能作为父类被继承。
-
finally:用于异常处理,必定要执行,一般用于释放资源。
-
finalize:是方法名java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除之前做必要的清理工作。
9.Log4j是什么?有什么作用?
- 它是开源的、来自Apache的一个第三方组件。
- 作用:做日志。