1. Java异常处理机制
1.1简单分类
Java把异常当作对象来处理,并定义了一个基类java.lang.Throwable作为所有异常的超类。
1.2 异常处理机制
- 抛出异常
- 捕获异常
1.2.1 异常处理的五个关键字
try、catch、finally、throw、throws
示例:
package Exception;
public class Test {
public static void main(String[] args) {
int a = 1;
int b = 0;
System.out.println(a / b);
}
}
改进后:
package Exception;
public class Test {
public static void main(String[] args) {
int a = 1;
int b = 0;
try {// 监控区域
System.out.println(a / b);
} catch (ArithmeticException e) {// 捕获异常
System.out.println("ArithmeticException");
} finally {// 处理善后工作 无论有没有异常 finally代码块都会执行
System.out.println("finally");
}
}
}
catch里面的参数是想要捕获的异常类型
try catch是一起出现的 finally是可选的,finally一般用来关闭资源。
可以多层捕获异常,单catch里面捕获的异常,从上往下应该是从小到大的,异常一旦被捕获,就不会执行后面的catch代码块了。
package Exception;
public class Test {
public static void main(String[] args) {
int a = 1;
int b = 0;
try {// 监控区域
System.out.println(a / b);
} catch (ArithmeticException e) {// 捕获异常
System.out.println("ArithmeticException");
} catch (Exception e) {
System.out.println("Exception");
} catch (Throwable e) {
System.out.println("Throwable");
} finally {// 处理善后工作 无论有没有异常 finally代码块都会执行
System.out.println("finally");
}
}
}
可以使用类似于e.printStackTrace();
的代码去打印错误的信息:
package Exception;
public class Test {
public static void main(String[] args) {
int a = 1;
int b = 0;
try {// 监控区域
System.out.println(a / b);
} catch (ArithmeticException e) {// 捕获异常
e.printStackTrace();
} finally {// 处理善后工作 无论有没有异常 finally代码块都会执行
System.out.println("finally");
}
}
}
1.3主动抛出异常
一般用在方法中
throw关键字是在语句中抛出异常。
package Exception;
public class Test {
public static void main(String[] args) {
test(1, 0);
}
public static void test(int a, int b) {
if (b == 0) {
throw new ArithmeticException();
} else {
System.out.println(a / 0);
}
}
}
throws关键字是在方法头抛出异常。假设该方法处理不了这个异常,就把它抛出去。
package Exception;
public class Test {
public static void main(String[] args) {
test(1, 0);
}
public static void test(int a, int b) throws ArithmeticException {
System.out.println(a / b);
}
}
1.4 自定义异常
使用java内置的异常类可以描述编程时出现的大部分异常情况,除此之外,用户还可以自定义异常。用户自定义异常类,只需要继承Exception类即可。
MyException.java
package Exception;
// 我自己的异常类
public class MyException extends Exception {
// 如果除数为0,就抛出异常
private int num;
public MyException(int num) {
this.num = num;
}
// toString:异常的打印信息
@Override
public String toString() {
return "MyException b can't be zero.";
}
}
Test.java
package Exception;
public class Test {
public static void main(String[] args) throws MyException {
division(1, 0);
}
// 可能会存在异常的方法
public static void division(int a, int b) throws MyException {
if (b == 0) {
throw new MyException(b);//抛出
} else {
System.out.println(a / b);
}
}
}
1.5 try(资源){} 格式自动关闭资源
作用: try块退出时,自动关闭括号里声明的资源,不再需要在finally里手动关闭资源
示例:
public void test() {
// 获取SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
// 执行sql
// 方式1: getMapper
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUserList();
// 方式2: 不推荐
// List<User> userList = sqlSession.selectList("com.tian.dao.UserDao.getUserList");
// userList.for IDEA快捷键
for (User user : userList) {
System.out.println(user);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭资源非常重要 关闭session
sqlSession.close();
}
}
等同于
public void test() {
// 获取SqlSession对象
// 自动关闭括号里声明的资源
try (SqlSession sqlSession = MybatisUtils.getSqlSession()) {
// 执行sql
// 方式1: getMapper
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUserList();
// 方式2: 不推荐
// List<User> userList = sqlSession.selectList("com.tian.dao.UserDao.getUserList");
// userList.for IDEA快捷键
for (User user : userList) {
System.out.println(user);
}
} catch (Exception e) {
e.printStackTrace();
}
// 关闭资源非常重要 关闭session
}
1.6实际应用中的经验总结
- 处理运行时异常时,采用逻辑去合理规避同时辅助 try-catch 处理。
- 在多重catch块后面,可以加上一个catch(Exception)来处理可能会被遗漏的异常。
- 对于不确定的代码,也可以加上try-catch 处理潜在的异常。
- 尽量去处理异常,切忌只是简单的调用printStackTrace()去打印输出。
- 具体如何处理异常,要根据不同的业务需求和异常类型去决定。
- 尽量添加finally语句块去释放占用的资源。