java-异常类(适合小白)
让我用生动的比喻来解释 Java 中的错误(Error)和异常(Exception)的区别:
🏠 把 Java 程序比作一栋房子:
什么是Throwable?
Throwable 类是 Java 语言中所有错误或异常的超类,是对所有异常进行整合的一个普通类。它的作用就是能够提取保存在堆栈中的错误信息。
1.错误(Error)
- 就像房子的地基出现严重问题或遭遇地震
- 是致命的、不可恢复的灾难性问题
- 例如:
- OutOfMemoryError:就像房子的承重墙突然倒塌
- StackOverflowError:就像楼层无限堆叠直到崩塌
2. 异常(Exception)
-
就像房子日常使用中遇到的各种小问题
-
是可以处理和修复的问题
-
分两种类型:
-
检查异常(Checked Exception)
- 像是预约水管工来修理漏水
- 必须提前计划如何处理
- 例如:FileNotFoundException(找不到文件)
-
非检查异常(Unchecked Exception)
- 像是不小心把花瓶打碎
- 是程序运行时突发的意外
- 例如:NullPointerException(空指针异常)
-
那么接下来再来理解这两句定义就会容易:
- 异常是指程序在编译或者运行时出现的某种异常问题,我们可以对异常进行某种处理,如果不处理异常的话,程序将会停止运行。
- 错误是指程序在运行时出现的严重问题,无法处理,程序将会停止运行,Error通常都是系统级别的问题,都是虚拟机jvm所在系统发生的,只能通过修改源代码解决问题。
自定义异常:
java无法为世界上所有的问题都提供异常类来代表,如果企业自己的某种问题,就需要自定义异常来管理问题。
运行时异常:
- 定义一个异常类继承RuntimeException
- 重写构造器
- 通过throw new 异常类(xxx)来创建异常对象并抛出
- 编译阶段不报错,提醒不强烈,运行时才可能出现!!
常见的运行时异常:
- 数组越界异常:ArrayIndexOutofBoundsException。
- 空指针异常:NullPointerException
- 类型转换异常:ClassCastException
- 迭代器遍历没有此元素异常:NoSuchElementException
- 数学操作异常:ArithemeticException.
- 数字转换异常:NumberFormatException.
编译时异常:
- 定义一个异常类继承Exception
- 重写构造器
- 通过throw new 异常类(xxx)来创建异常对象并抛出
- 编译阶段就报错,提醒更加强烈!!
例子:
自定义编译时异常类:
public class IntegerException extends Exception {
String message;
public IntegerException(int m) {
message="年龄"+m+"不合理";
}
public String toString() {
return message;
}
}
注意:
throws 用在方法上,抛出方法内部的异常给上一级,运行时异常是自动抛出的,不用手动抛出
public void readFile() throws IOException {
// 可能会抛出IOException的代码
}
throw 抛出这个异常对象
public void checkAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数");
}
}
throw和throws的区别:
- throw关键字通常用于手动抛出异常,而throws关键字通常用于声明方法可能抛出的异常。
- throw关键字只能抛出一个异常对象,而throws关键字可以同时指定多个异常。
- throw关键字会中断当前的执行流程,寻找合适的异常处理机制,而throws关键字将异常传递给调用者来处理。
异常处理常用的方式:
这里需要先了解捕获异常的语法:
捕获异常:Java中对异常有针对性的语句进行捕获,可以对出现的异常进行指定方式的处理
语句格式:
try {
//需要被检测的语句。
}
catch(异常类1 变量) { //参数。
//异常的处理语句。
}
catch(异常类2 变量) { //参数。
//异常的处理语句。
}
finally {
//一定会被执行的语句。
}
方法一:
捕获异常,记录异常并响应给用户
举例:
public class Exception {
public static void main(String[] args) {
try {
test1();
}catch (FileNotFoundException e){
System.out.println("文件不存在");
e.printStackTrace();
}catch (ParseException e){
System.out.println("日期格式错误");
e.printStackTrace();
}
}
public static void test1() throws ParseException, FileNotFoundException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse("2024-11-17 10:00");
System.out.println(d);
test2();
}
public static void test2() throws FileNotFoundException {
//读取文件错误
InputStream is = new FileInputStream("D:meinv.jpg");
}
}
逻辑图看这个: 执行逻辑,小白要着重搞懂逻辑顺序,很重要
方法二:
捕获异常,并尝试修复
public class Exception_Test2 {
public static void main(String[] args) {
// 需求:调用一个方法,让用户输入一个合适的价格返回为止
// 尝试修复
while (true) {
try {
System.out.println(getPrice());
break;
} catch (Exception e) {
System.out.println("请您输入合适的数字!");
}
}
}
public static double getPrice() {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("请输入一个合适的价格:");
double price = scanner.nextDouble();//不能识别字符串
if (price > 0) {
return price;
} else {
System.out.println("价格不合适");
}
}
}
}
逻辑图:
方法三:
-
Throws异常处理方法:
在开发中,有的时候我们没有权限处理该异常,我们不知道该如何处理异常,或者不想处理异常,这种情况下我们可以将异常抛出,抛出给调用者JVM处理 -
throws处理异常的格式:
[访问权限修饰符] 返回值类型 方法名(参数列表) [throws 异常类名]{
方法体;
[return 返回值];
}
-
注意事项:
可以一直向上一级抛出异常,但是不建议抛出给JVM,因为那样程序会终止。
🔧 处理方式:
- 错误:需要关闭程序,就像严重地震后必须疏散房屋
- 异常:可以通过 try-catch 处理,就像及时修理房屋中的小问题
📝 总结:
- 错误:严重事故 → 无法恢复 → 必须停止程序
- 异常:小问题 → 可以修复 → 程序可以继续运行