一.自定义异常类
在开发中根据自己业务的异常情况来定义异常类.
- 自定义一个受检查的异常类;自定义类,并继承java.lang.Exception
- 自定义一个运行时期的异常类;自定义类,并继承于java.lang.RuntimeException
新建LogicException.java
public class LogicException extends RuntimeException{
public LogicException(String message, Throwable cause) {
super(message, cause);
}
public LogicException(String message) {
super(message);
}
}
新建测试异常类RegisterDemo.java
public class RegisterDemo {
private static final String[] names = new String[]{"huangkun","lucy","lily"};
public static void main(String[] args) {
try {
checkUsername("huangkun");
System.out.println("注册成功!");
}catch(LogicException e) {
System.out.print("给亲看:");
System.out.println(e.getMessage());
}
}
private static boolean checkUsername(String string) throws LogicException{
for (String name : names) {
if (name.equals(string)) {
throw new LogicException("亲,这个账号已经存在了哦~~");
}
}
return true;
}
}
综合例子
新建SynthesizeException.java
//车坏异常
class CardWrongException extends RuntimeException{
public CardWrongException(String message, Throwable cause) {
super(message, cause);
}
public CardWrongException(String message) {
super(message);
}
}
//迟到异常
class LateException extends RuntimeException{
public LateException(String message, Throwable cause) {
super(message, cause);
}
public LateException(String message) {
super(message);
}
}
class Card{
void run() {
int i = 1;
if(i == 2) {
throw new CardWrongException("车爆胎了");
}
System.out.println("开车去上班");
}
}
class Worker{
Card card =null;
Worker(Card card){
this.card = card;
}
void goWork() {
try{
card.run();
System.out.println("全勤");
}catch(Exception e) {
System.out.println(e.getMessage());
System.out.println("走路去上班");
throw new LateException("上班迟到了");
}
}
}
public class SynthesizeExceptionDemo{
public static void main(String[] args) {
Card card = new Card();
Worker worker = new Worker(card);
try {
worker.goWork();
System.out.println("发奖金");
}catch(Exception e) {
System.out.println("扣工资");
}
}
}
二.异常转译和异常链
- 异常转译:当位于最上层的子系统不需要关心底层的异常细节时,常见的做法是捕获原始的异常,把它转换成新类型的异常,再抛出新的异常.
- 异常链:把原始的异常包装为新的异常类,从而形成多个异常的有序排列,有助于查找异常的根本原因
三.处理异常的原则
- 异常只能用于非正常情况,try-catch的存在会影响性能
- 需要为异常提供说明文档,比如Java doc
- 尽可能避免异常(如NullPointerException)
- 异常的粒度很重要,应该为一个基本操作定义一个try-catch块,不要为了方便,将几百行代码放到一个
try-catch中 - 自定义异常尽量使用RuntimeExecption类型的
四.异常相关面试题
- Error和Exception的区别和关系
- checked异常和runtime异常的区别
- 如何保证一段代码必须执行到(finnally)
- finally中的代码一定会执行吗?
- finally和return的执行顺序
- throw和throws的区别
- 列举5个常见异常类
- 列举5个常见的Runtime 异常类
- ArithmeticException: 算数异常
- NullPointerException: 空指针异常
- ArrayIndexOutOfBoundsException: 数组索引越界
- StringIndexOutOfBoundsException: String操作中索引越界
- ClassCastException: 类型强制转换异常
- NumberFormatException 类型强制转换异常