异常处理
Java异常
-
调用方法如何获取调用失败的信息:
-
约定返回错误码;
int code = processFile("C:/demo.txt"); if (code == 0) { // ok: } else { // error: switch (code) { case 1: // file not found: case 2: // no read permission: default: // unknown error: } }
-
在语言层面提供一个异常处理机制;
try { String s = processFile("C:/demo.txt"); // ok: } catch (FileNotFoundException e) { // file not found: } catch (SecurityException e) { // no read permission: } catch (IOException e) { // io error: } catch (Exception e) { // other error: }
-
-
Java
异常的分类- 必须捕获的异常,包括
Exception
及其子类,但不包含RuntimeException
及其子类,此种类型异常被称为Checked Exception
; - 无需捕获的异常,包括
Error
及其子类,RuntimeException
及其子类;
- 必须捕获的异常,包括
异常捕获
异常捕获使用try...catch
语句,将可能发生异常的代码放入try{...}
中,然后使用catch
捕获对应Exception
及其子类。当有多个catch
语句时,JVM
会从上到下匹配catch
语句,直到匹配某一catch
后不再执行,注意:catch
的顺序要将子类放在前边;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
byte[] bs = toGBK("中文");
System.out.println(Arrays.toString(bs));
}
static byte[] toGBK(String s) {
try {
// 用指定编码转换String为byte[]:
return s.getBytes("GBK");
} catch (UnsupportedEncodingException e) {
// 如果系统不支持GBK编码,会捕获到UnsupportedEncodingException:
e.printStackTrace();
System.out.println(e); // 打印异常信息
return s.getBytes(); // 尝试使用用默认编码
}
}
}
-
finally
:捕获异常时,不论是否发生异常,都将执行finally
中的语句,主要有如下特点:finally
非必须,可写可不写;finally
总是最后执行;
public static void main(String[] args) { try { process1(); process2(); process3(); } catch (UnsupportedEncodingException e) { System.out.println("Bad encoding"); } catch (IOException e) { System.out.println("IO error"); } finally { System.out.println("END"); } }
异常抛出
-
当程序中的某一方法抛出异常时,若当前方法未捕获异常,异常就会被抛到上层调用方法,直到遇见某一
try...catch
被捕获; -
抛出异常的步骤:
- 创建某个
Exception
的实例; - 用
throw
语句抛出;
void process(String str){ if(str == null){ // 创建某个Exception的实例 NullPointerException e = new NullPointerException(); // throw语句抛出 throw e; // 上述步骤可合并为一行,等价于 // throw new NullPointerException(); } }
- 创建某个
-
在
catch
中抛出异常时,不会影响finally
的执行,JVM
会优先执行finally
,然后再抛出异常; -
异常屏蔽
在
finally
执行时若抛出异常,catch
中的异常就会被屏蔽,但是可以通过将原始异常进行保存,然后调用Throwable.addSuppresssed()
,将原始异常添加出来,最后在finally
中抛出;扫描二维码关注公众号,回复: 10050614 查看本文章public class Main{ public static void main(String[] args){ Exception origin = null; try{ System.out.println(Interger.parseInt("ab")); }catch(Exception e){ origin = e; throw e; }finally{ Exception e = new IllegalArgumentException(); if(origin != null){ e.addSuppressed(origin); } throw e; } } }
自定义异常
-
Java
标准库定义的常用异常: -
自定义异常时,推荐从
RuntimeException
派生根异常,再派生出业务异常,而且需要提供多种构造方法;
断言
断言(Assertion
)是一种调试程序的方式,利用assert
关键字来实现断言。当断言失败时会抛出AssertionError
,导致程序退出,只适合在开发和测试阶段启用;
public static void main(String args){
double x = Math.abs(-123.4);
assert x >= 0;
System.out.println(x);
}
JDK Logging
Logging
定义了7个日志级别,从严重到普通:SEVERE
WARNING
INFO
(默认级别)CONFIG
FINE
FINER
FINEST
Logging
存在的局限:Logging
系统在JVM
启动时会读取配置文件并完成初始化,一旦开始main()
方法,就不能再改配置;- 配置不方便,需要在
JVM
启东市传递参数-Djava.util.logging.config.file=<config-file-name>
;
import java.io.UnsupportedEncodingException;
import java.util.logging.Logger;
public class Main(){
public static void main(String[] args){
Logger logger = Logger.getLogger(Main.class.getName());
logger.info("进程开始。。。");
try{
"".getBytes("不可用的字符集");
}catch(UnsupportedEncodingException e){
e.printStackTrace();
logger.severe(e.toString());
}
logger.info("进程结束");
}
}
Commons Logging
-
由
Apache
创建的第三方日志模块,可以挂接不通日志系统,并通过配置文件制定挂接的日志系统; -
Commons Logging
只需与两个类打交道,且只需要两步:- 通过
LogFactory
获取Log
类的实例; - 使用
Log
实例的方法打印日志;
- 通过
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Main{
public static void main(String[] args){
Log log = LogFactory.getLog(Main.class);
log.info("开始。。。");
log.warn("结束。。。")
}
}
Commons Logging
的6个日志级别:FATAL
ERROR
WARNING
INFO
(默认级别)DEBUGE
TRACE
Log4j
-
Log4j
时一个组件化设计的日志系统,其架构如下: -
Log4j
输出日志的不同目的地:关键字 功能 console
输出到屏幕 file
输出到文件 socket
通过网络输出到远程计算机 jdbc
输出到数据库