throw 关键字

概述

throw 关键字用于手动抛出异常,可以抛出系统定义的异常或自定义异常。

语法格式

throw new ExceptionType("异常消息");
throw exceptionObject;

基本用法

public class ThrowExample {

    public static void validateAge(int age) {
        if (age < 0) {
            throw new IllegalArgumentException("年龄不能为负数");
        }
        if (age > 150) {
            throw new IllegalArgumentException("年龄不能超过150岁");
        }
        System.out.println("年龄验证通过: " + age);
    }

    public static double divide(double a, double b) {
        if (b == 0) {
            throw new ArithmeticException("除数不能为0");
        }
        return a / b;
    }

    public static void main(String[] args) {
        try {
            validateAge(25);   // 正常
            validateAge(-5);   // 抛出异常
        } catch (IllegalArgumentException e) {
            System.out.println("参数错误: " + e.getMessage());
        }

        try {
            double result = divide(10, 0);
            System.out.println("结果: " + result);
        } catch (ArithmeticException e) {
            System.out.println("计算错误: " + e.getMessage());
        }
    }
}

自定义异常

// 自定义检查异常
class InsufficientBalanceException extends Exception {
    private double balance;
    private double amount;

    public InsufficientBalanceException(double balance, double amount) {
        super("余额不足:当前余额 " + balance + ",尝试取款 " + amount);
        this.balance = balance;
        this.amount = amount;
    }

    public double getBalance() { return balance; }
    public double getAmount() { return amount; }
}

// 自定义运行时异常
class InvalidAccountException extends RuntimeException {
    public InvalidAccountException(String message) {
        super(message);
    }

    public InvalidAccountException(String message, Throwable cause) {
        super(message, cause);
    }
}

public class CustomExceptionExample {

    public static void withdraw(double balance, double amount) 
            throws InsufficientBalanceException {
        if (amount <= 0) {
            throw new InvalidAccountException("取款金额必须大于0");
        }

        if (amount > balance) {
            throw new InsufficientBalanceException(balance, amount);
        }

        System.out.println("取款成功:" + amount + ",剩余余额:" + (balance - amount));
    }

    public static void main(String[] args) {
        try {
            withdraw(1000, 500);  // 正常取款
            withdraw(1000, 1500); // 余额不足
        } catch (InsufficientBalanceException e) {
            System.out.println("取款失败: " + e.getMessage());
            System.out.println("当前余额: " + e.getBalance());
            System.out.println("尝试金额: " + e.getAmount());
        }

        try {
            withdraw(1000, -100); // 无效金额
        } catch (InvalidAccountException e) {
            System.out.println("账户操作错误: " + e.getMessage());
        } catch (InsufficientBalanceException e) {
            System.out.println("余额不足: " + e.getMessage());
        }
    }
}

异常链

import java.io.*;

public class ExceptionChainExample {

    public static void readConfiguration(String filename) throws Exception {
        try {
            FileInputStream fis = new FileInputStream(filename);
            // 读取配置文件
            fis.close();
        } catch (FileNotFoundException e) {
            // 包装原始异常,创建异常链
            throw new Exception("配置文件加载失败: " + filename, e);
        } catch (IOException e) {
            throw new Exception("读取配置文件时发生IO错误", e);
        }
    }

    public static void initializeApplication() throws Exception {
        try {
            readConfiguration("app.properties");
        } catch (Exception e) {
            // 再次包装异常
            throw new Exception("应用程序初始化失败", e);
        }
    }

    public static void main(String[] args) {
        try {
            initializeApplication();
        } catch (Exception e) {
            System.out.println("最终错误: " + e.getMessage());

            // 打印异常链
            Throwable cause = e.getCause();
            while (cause != null) {
                System.out.println("原因: " + cause.getMessage());
                cause = cause.getCause();
            }

            System.out.println("\n完整堆栈跟踪:");
            e.printStackTrace();
        }
    }
}

业务逻辑中的异常抛出

import java.util.*;

// 用户管理系统示例
public class UserManagementExample {

    // 自定义业务异常
    static class UserNotFoundException extends Exception {
        public UserNotFoundException(String userId) {
            super("用户未找到: " + userId);
        }
    }

    static class DuplicateUserException extends Exception {
        public DuplicateUserException(String userId) {
            super("用户已存在: " + userId);
        }
    }

    static class InvalidUserDataException extends RuntimeException {
        public InvalidUserDataException(String message) {
            super(message);
        }
    }

    // 用户类
    static class User {
        private String id;
        private String name;
        private String email;

        public User(String id, String name, String email) {
            this.id = id;
            this.name = name;
            this.email = email;
        }

        // Getters
        public String getId() { return id; }
        public String getName() { return name; }
        public String getEmail() { return email; }

        @Override
        public String toString() {
            return "User{id='" + id + "', name='" + name + "', email='" + email + "'}";
        }
    }

    // 用户服务
    static class UserService {
        private Map<String, User> users = new HashMap<>();

        public void createUser(String id, String name, String email) 
                throws DuplicateUserException {
            // 数据验证
            validateUserData(id, name, email);

            // 检查用户是否已存在
            if (users.containsKey(id)) {
                throw new DuplicateUserException(id);
            }

            User user = new User(id, name, email);
            users.put(id, user);
            System.out.println("用户创建成功: " + user);
        }

        public User findUser(String id) throws UserNotFoundException {
            if (id == null || id.trim().isEmpty()) {
                throw new InvalidUserDataException("用户ID不能为空");
            }

            User user = users.get(id);
            if (user == null) {
                throw new UserNotFoundException(id);
            }

            return user;
        }

        public void deleteUser(String id) throws UserNotFoundException {
            User user = findUser(id); // 可能抛出UserNotFoundException
            users.remove(id);
            System.out.println("用户删除成功: " + user);
        }

        private void validateUserData(String id, String name, String email) {
            if (id == null || id.trim().isEmpty()) {
                throw new InvalidUserDataException("用户ID不能为空");
            }

            if (name == null || name.trim().isEmpty()) {
                throw new InvalidUserDataException("用户名不能为空");
            }

            if (email == null || !email.contains("@")) {
                throw new InvalidUserDataException("邮箱格式不正确");
            }
        }

        public void listUsers() {
            if (users.isEmpty()) {
                System.out.println("没有用户");
            } else {
                System.out.println("用户列表:");
                users.values().forEach(System.out::println);
            }
        }
    }

    public static void main(String[] args) {
        UserService service = new UserService();

        try {
            // 正常创建用户
            service.createUser("001", "张三", "zhangsan@example.com");
            service.createUser("002", "李四", "lisi@example.com");

            // 尝试创建重复用户
            service.createUser("001", "王五", "wangwu@example.com");

        } catch (DuplicateUserException e) {
            System.out.println("创建失败: " + e.getMessage());
        } catch (InvalidUserDataException e) {
            System.out.println("数据验证失败: " + e.getMessage());
        }

        try {
            // 查找用户
            User user = service.findUser("001");
            System.out.println("找到用户: " + user);

            // 查找不存在的用户
            service.findUser("999");

        } catch (UserNotFoundException e) {
            System.out.println("查找失败: " + e.getMessage());
        } catch (InvalidUserDataException e) {
            System.out.println("参数错误: " + e.getMessage());
        }

        try {
            // 删除用户
            service.deleteUser("002");

            // 删除不存在的用户
            service.deleteUser("999");

        } catch (UserNotFoundException e) {
            System.out.println("删除失败: " + e.getMessage());
        }

        // 显示剩余用户
        service.listUsers();
    }
}

最佳实践

public class ThrowBestPractices {

    // 1. 抛出有意义的异常
    public static void processFile(String filename) {
        if (filename == null) {
            throw new IllegalArgumentException("文件名不能为null");
        }

        if (filename.trim().isEmpty()) {
            throw new IllegalArgumentException("文件名不能为空");
        }

        // 处理文件...
    }

    // 2. 保持异常消息清晰
    public static void withdraw(double balance, double amount) {
        if (amount <= 0) {
            throw new IllegalArgumentException(
                String.format("取款金额无效: %.2f (必须大于0)", amount));
        }

        if (amount > balance) {
            throw new IllegalStateException(
                String.format("余额不足: 当前%.2f, 尝试取款%.2f", balance, amount));
        }
    }

    // 3. 在合适的抽象级别抛出异常
    public static void saveUserData(String userData) throws DataPersistenceException {
        try {
            // 底层数据库操作
            performDatabaseOperation(userData);
        } catch (SQLException e) {
            // 将低级别的数据库异常转换为业务级别的异常
            throw new DataPersistenceException("保存用户数据失败", e);
        }
    }

    // 4. 避免过度使用异常
    public static boolean isValidEmail(String email) {
        // 好的做法:返回boolean而不是抛出异常
        return email != null && email.contains("@");
    }

    // 避免这样做:
    // public static void validateEmail(String email) {
    //     if (!email.contains("@")) {
    //         throw new IllegalArgumentException("邮箱格式不正确");
    //     }
    // }

    // 模拟方法
    private static void performDatabaseOperation(String data) throws SQLException {
        throw new SQLException("模拟数据库错误");
    }

    // 自定义异常类
    static class DataPersistenceException extends Exception {
        public DataPersistenceException(String message, Throwable cause) {
            super(message, cause);
        }
    }

    static class SQLException extends Exception {
        public SQLException(String message) {
            super(message);
        }
    }
}

throw关键字是Java异常处理的重要组成部分,正确使用它可以让程序的错误处理更加清晰和健壮。

powered by Gitbook© 2025 编外计划 | 最后修改: 2025-07-28 16:25:54

results matching ""

    No results matching ""