异常机制:
异常机制是指当程序出现错误后,程序如何处理。具体来说就是程序发生异常,异常机制提供程序的退出安全通道。
通俗来说:就是为了让程序继续执行下去,不至于中断。
程序错误:
程序错误分为三种:
1.编译错误
2.运行时错误
3.逻辑错误。
(1)编译错误:因为程序没有遵循语法规则,编译程序能够自己发现并提示我们的错误的原因和位置。
(2)运行时错误:因为程序在执行时,运行环境发现了不能执行的操作。
(3)逻辑错误:因为程序没有按照预期的逻辑顺序执行。
异常就是指程序运行时发生错误,而异常处理就是对这些错误进行处理和控制。
编译错误如下:
运行错误如下:
算数异常报错:
常见异常:
序号 | 异常名称 | 异常描述 |
---|---|---|
1 | java.lang.NullPointerException | 空指针异常:对象为空,并且调用相应方法。 |
2 | java.lang.ClassNotFoundException | 找不到指定类 |
3 | java.lang.ArrayIndexOutOfBoundsException | 数组下标越界 |
4 | java.lang.NumberFormatException | 数字格式化异常 |
5 | java.lang.ArithmeticException | 数学运算异常 |
6 | java.lang.StackOverflowError | 内存空间溢出错误,方法递归调用中,经常发生 |
7 | java.lang.ClassCastException | 类型转换异常,向下转型中经常发生 |
8 | java.text.ParseException | 时间格式化异常,SimpleDateFormart中经常发生 |
9 | java.util.InputMismatchException | 输入类型不匹配异常 |
虚拟机对异常的两种处理方式:
捕获异常
try - catch - finally
try{ //可能会出错的代码块 }catch(){ //出现异常后,执行的语句 }finally{ //通常用来释放资源 }
运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常
public void fun1() throws ParseException { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = format.parse("2020-10-12"); }
throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。
public void fun2() { throw new NullPointerException("空指针异常"); System.out.println("hello world");//会报红,提示unreachable statement,该语句不可能被执行 }
@Test public void fun2() { try { throw new Exception("非运行时异常,哈哈哈"); } catch (Exception e) { e.printStackTrace(); try { throw new ParseException("解析异常,哈哈哈",0); } catch (Exception ex) { ex.printStackTrace(); } }finally { try { throw new TimeoutException("超时异常,哈哈哈"); } catch (TimeoutException e) { e.printStackTrace(); try { throw new SQLException("SQL异常"); } catch (SQLException ex) { ex.printStackTrace(); } } } }
public int funR1(){ try { return 1; }catch (Exception e){ throw new RuntimeException(); } } public int funR2(){ if(true) { return 1; }else{ throw new RuntimeException(); } }
自定义异常,通常就是定义了一个继承自Exception类的子类,那么这个类就是一个自定义异常类。通常情况下,我们都会直接继承自Exception,一般不会继承某个运行时异常类。
案例如下:
public class HeroNotExistException extends RuntimeException { private String m; public String getM() { return m; } public void setM(String m) { this.m = m; } //两个参数的有参构造,一个传递给父类Throwable,一个自己用 public HeroNotExistException(String message, String m){ super(message); this.m=m; } public static void main(String[] args) { Scanner sc=new Scanner(System.in); System.out.println("请输入您最欣赏的历史人物:"); String name = sc.next(); if(name.equals("孙悟空")){ try{ throw new HeroNotExistException("英雄人物不存在","哈哈"); }catch (HeroNotExistException e){ e.printStackTrace(); System.out.println(e.getM()); } } } }