java基础-9 : 异常
一.try-catch
异常是程序执行过程中发生的非正常事件,会中断正常的指令流。

package 异常;
public class BasicTryCatch {public static void main(String[] args) {int[] arr = {1, 2, 3, 4, 5};try {System.out.println("尝试访问数组...");System.out.println(arr[10]); // 这里会抛出异常System.out.println("这行代码不会执行"); // 异常后的代码不会执行} catch (ArrayIndexOutOfBoundsException e) {System.out.println("捕获到数组越界异常!");System.out.println("getMessage: " + e.getMessage());System.out.println("toString: " + e.toString());System.out.println("printStackTrace:");e.printStackTrace();}System.out.println("程序继续正常执行...");}
}
尝试访问数组...
捕获到数组越界异常!
getMessage: Index 10 out of bounds for length 5
toString: java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 5
printStackTrace:
java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 5at 异常.BasicTryCatch.main(BasicTryCatch.java:7)
程序继续正常执行...1.多个catch
catch块必须从具体到抽象
父类Exception必须放在最后
一旦匹配到catch块,其他catch块不再执行
package 异常;
public class MultipleCatch {public static void main(String[] args) {try {String str = null;int[] arr = {1, 2, 3};if (Math.random() > 0.5) {System.out.println(str.length()); // NullPointerException} else {System.out.println(arr[10]); // ArrayIndexOutOfBoundsException}} catch (NullPointerException e) {System.out.println("空指针异常: " + e.getMessage());} catch (ArrayIndexOutOfBoundsException e) {System.out.println("数组越界异常: " + e.getMessage());} catch (Exception e) {System.out.println("其他异常: " + e.getMessage());// 父类Exception必须放在最后}}
}
数组越界异常: Index 10 out of bounds for length 32.多重捕获
package 异常;
public class MultiCatch {public static void main(String[] args) {try {String input = "abc";int number = Integer.parseInt(input); // NumberFormatExceptionint[] arr = null;System.out.println(arr.length); // NullPointerException} catch (NumberFormatException | NullPointerException e) {// 使用 | 同时捕获多种异常System.out.println("数据格式错误或空指针: " + e.getClass().getSimpleName());System.out.println("异常信息: " + e.getMessage());}// 注意:多重捕获的异常不能有继承关系// catch (Exception | RuntimeException e) { } // 编译错误!}
}
数据格式错误或空指针: NumberFormatException
异常信息: For input string: "abc"二.try-catch-finally
执行try块中的代码
如果发生异常,立即跳转到对应的catch块
执行catch块中的异常处理代码
执行finally块中的代码(总是执行)
继续执行后续代码
package 异常;import java.util.InputMismatchException;
import java.util.Scanner;public class FinallyExample {public static void main(String[] args) {testFinally();}public static void testFinally() {Scanner scanner = new Scanner(System.in);try {System.out.println("请输入一个数字:");int num = scanner.nextInt();System.out.println("输入的数字是: " + num);if (num < 0) {throw new IllegalArgumentException("数字不能为负数");}} catch (InputMismatchException e) {System.out.println("输入格式错误!");} catch (IllegalArgumentException e) {System.out.println("参数错误: " + e.getMessage());} finally {// 无论是否发生异常,finally块都会执行System.out.println("执行finally块 - 清理资源");scanner.close(); // 重要:关闭资源}System.out.println("方法执行完毕");}
}三.throw+throws
- throws:写在方法定义处,用于表示该方法可能会抛出的异常类型
- throw:用于方法体中,用于手动抛出异常
1.throw-手动抛出异常
package 异常;
public class ThrowExample {public static void main(String[] args) {try {validateAge(15); // 年龄太小validateAge(25); // 正常年龄validateAge(-5); // 无效年龄} catch (IllegalArgumentException e) {System.out.println("捕获异常: " + e.getMessage());}}public static void validateAge(int age) {if (age < 0) {throw new IllegalArgumentException("年龄不能为负数: " + age);}if (age < 18) {throw new IllegalArgumentException("年龄太小,必须年满18岁: " + age);}if (age > 120) {throw new IllegalArgumentException("年龄太大,不现实: " + age);}System.out.println("年龄验证通过: " + age);}
}
捕获异常: 年龄太小,必须年满18岁: 152.throws-声明抛出异常
在方法签名中声明该方法可能抛出的异常
package 异常;import java.io.*;public class ThrowsExample {public static void main(String[] args) {// 方式1: 在调用处处理异常safeReadFile("test.txt");// 方式2: 继续抛出异常try {String content = readFile("nonexistent.txt");} catch (IOException e) {System.out.println("主方法中处理异常: " + e.getMessage());}}public static String readFile(String filename) throws FileNotFoundException, IOException {// 受检异常必须声明或处理BufferedReader reader = new BufferedReader(new FileReader(filename));try {StringBuilder content = new StringBuilder();String line;while ((line = reader.readLine()) != null) {content.append(line).append("\n");}return content.toString();} finally {reader.close();}}public static void safeReadFile(String filename) {try {String content = readFile(filename);System.out.println("文件内容: " + content);} catch (FileNotFoundException e) {System.out.println("文件不存在: " + filename);} catch (IOException e) {System.out.println("读取文件时发生IO错误: " + e.getMessage());}}}四.自定义异常
runtimeException:核心是由于参数错误而导致的问题
Exception:核心在于提醒程序员检查本地信息
1.自定义运行时异常
package 异常;
public class myselfException extends RuntimeException {private String errorCode;private String errorMsg;public myselfException(String errorCode, String errorMsg) {super(errorCode + ": " + errorMsg);this.errorCode = errorCode;this.errorMsg = errorMsg;}public myselfException(String errorMsg) {super(errorMsg);this.errorCode = "BUSINESS_ERROR";this.errorMsg = errorMsg;}// Getter方法public String getErrorCode() { return errorCode; }public String getErrorMsg() { return errorMsg; }@Overridepublic String toString() {return "myselfException{" +"errorCode='" + errorCode + '\'' +", errorMsg='" + errorMsg + '\'' +'}';}
}2.自定义编译时异常
package 异常;
public class ValidationException extends Exception {private String fieldName;private Object invalidValue;public ValidationException(String message, String fieldName, Object invalidValue) {super(message);this.fieldName = fieldName;this.invalidValue = invalidValue;}// Getter方法public String getFieldName() { return fieldName; }public Object getInvalidValue() { return invalidValue; }@Overridepublic String getMessage() {return String.format("字段 '%s' 的值 '%s' 无效: %s",fieldName, invalidValue, super.getMessage());}
}3.测试结果
package 异常;
public class ExceptionDemo {public static void main(String[] args) {UserService userService = new UserService();try {// 测试自定义运行时异常userService.registerUser("", 15);} catch (myselfException e) {System.out.println("业务异常: " + e.getErrorCode() + " - " + e.getErrorMsg());e.printStackTrace();}try {// 测试自定义受检异常userService.validateEmail("invalid-email");} catch (ValidationException e) {System.out.println("验证异常: " + e.getMessage());}}
}class UserService {public void registerUser(String username, int age) {if (username == null || username.trim().isEmpty()) {throw new myselfException("USER_001", "用户名不能为空");}if (age < 18) {throw new myselfException("USER_002", "用户年龄必须大于18岁");}if (username.length() < 3) {throw new myselfException("USER_003", "用户名长度至少3个字符");}System.out.println("用户注册成功: " + username);}public void validateEmail(String email) throws ValidationException {if (email == null || !email.contains("@")) {throw new ValidationException("邮箱格式不正确", "email", email);}System.out.println("邮箱验证通过: " + email);}
}
业务异常: USER_001 - 用户名不能为空
验证异常: 字段 'email' 的值 'invalid-email' 无效: 邮箱格式不正确
BusinessException{errorCode='USER_001', errorMsg='用户名不能为空'}at 异常.UserService.registerUser(ExceptionDemo.java:27)at 异常.ExceptionDemo.main(ExceptionDemo.java:8)五.练习
package 异常;import java.util.Scanner;public class test6 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);gril g = new gril();while (true) {try {System.out.println("请输入姓名");String name = sc.nextLine();g.setName(name);System.out.println("请输入年龄");String ageStr = sc.nextLine();int age = Integer.parseInt(ageStr);g.setAge(age);break;//因为如果没有异常则会执行到这一步,有异常则直接到catch中} catch (NumberFormatException e) {System.out.println("年龄格式错误");} catch (RuntimeException e) {System.out.println("姓名或年龄格式错误");}}System.out.println(g);}
}
