Javaexceptionprocessingtutorial

Learningexceptionclass型, try-catch-finally语句, throws and throw关键字 - core concepts

返回tutoriallist

Javaexceptionprocessingtutorial

Javaexceptionprocessing is Javaprogrammingin important concepts, 它允许程序 in 遇 to error时able to优雅地processingexceptioncircumstances, 而不 is 直接崩溃. 本tutorial将详细介绍Javaexceptionprocessing core concepts and 实践techniques, helping您writing更加健壮 Java程序.

1. exceptionoverview

1.1 what is exception?

exception is 程序run过程in发生 意 out circumstances, 它会in断程序 正常执行流程. 例such as, 除以零, arrayindex越界, file不存 in etc.circumstances都会导致exception.

1.2 exception classification

Javain exception分 for 两 big class:

  • Checked Exception (受检exception) : 必须 in codein显式processing exception, such asIOException, SQLExceptionetc..
  • Unchecked Exception (非受检exception) : 不需要 in codein显式processing exception, such asRuntimeException, NullPointerExceptionetc..

1.3 exception层次structure

Java exception层次structure以Throwable for 根class, 它 has 两个直接子class:

  • Error: 表示严重 error, 程序一般无法restore, such asOutOfMemoryError, StackOverflowErroretc..
  • Exception: 表示程序可以processing exception, is 我们主要关注 class型.

2. exceptionprocessingmechanism

2.1 try-catch语句

public class TryCatchExample {
    public static void main(String[] args) {
        try {
            int[] numbers = {1, 2, 3};
            System.out.println(numbers[5]); // arrayindex越界
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("发生exception: " + e.getMessage());
        }
        System.out.println("程序继续执行");
    }
}

2.2 try-catch-finally语句

public class TryCatchFinallyExample {
    public static void main(String[] args) {
        try {
            int result = 10 / 0; // 除以零
            System.out.println("结果: " + result);
        } catch (ArithmeticException e) {
            System.out.println("发生exception: " + e.getMessage());
        } finally {
            System.out.println("无论 is 否发生exception, finally块都会执行");
        }
        System.out.println("程序继续执行");
    }
}

2.3 many 个catch块

public class MultipleCatchExample {
    public static void main(String[] args) {
        try {
            String str = null;
            System.out.println(str.length()); // 空指针exception
            int[] numbers = {1, 2, 3};
            System.out.println(numbers[5]); // arrayindex越界
        } catch (NullPointerException e) {
            System.out.println("空指针exception: " + e.getMessage());
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("arrayindex越界exception: " + e.getMessage());
        } catch (Exception e) {
            System.out.println("otherexception: " + e.getMessage());
        }
        System.out.println("程序继续执行");
    }
}

2.4 try-with-resources语句

import java.io.FileReader;
import java.io.IOException;

public class TryWithResourcesExample {
    public static void main(String[] args) {
        try (FileReader reader = new FileReader("example.txt")) {
            int character;
            while ((character = reader.read()) != -1) {
                System.out.print((char) character);
            }
        } catch (IOException e) {
            System.out.println("IOexception: " + e.getMessage());
        }
        // 不需要显式关闭resource, try-with-resources会自动关闭
    }
}

3. 抛出exception

3.1 throw关键字

public class ThrowExample {
    public static void checkAge(int age) {
        if (age < 18) {
            throw new IllegalArgumentException("年龄必须 big 于etc.于18岁");
        }
        System.out.println("年龄合法: " + age);
    }
    
    public static void main(String[] args) {
        try {
            checkAge(15);
        } catch (IllegalArgumentException e) {
            System.out.println("发生exception: " + e.getMessage());
        }
    }
}

3.2 throws关键字

import java.io.IOException;

public class ThrowsExample {
    public static void readFile() throws IOException {
        FileReader reader = new FileReader("example.txt");
        reader.close();
    }
    
    public static void main(String[] args) {
        try {
            readFile();
        } catch (IOException e) {
            System.out.println("IOexception: " + e.getMessage());
        }
    }
}

4. 自定义exception

in Javain, 我们可以throughinheritanceException or RuntimeExceptionclass来creation自定义exception.

// 自定义受检exception
class AgeException extends Exception {
    public AgeException(String message) {
        super(message);
    }
}

// 自定义非受检exception
class ScoreException extends RuntimeException {
    public ScoreException(String message) {
        super(message);
    }
}

public class CustomExceptionExample {
    public static void checkAge(int age) throws AgeException {
        if (age < 18) {
            throw new AgeException("年龄必须 big 于etc.于18岁");
        }
        System.out.println("年龄合法: " + age);
    }
    
    public static void checkScore(int score) {
        if (score < 0 || score > 100) {
            throw new ScoreException("分数必须 in 0-100之间");
        }
        System.out.println("分数合法: " + score);
    }
    
    public static void main(String[] args) {
        try {
            checkAge(15);
        } catch (AgeException e) {
            System.out.println("发生exception: " + e.getMessage());
        }
        
        try {
            checkScore(105);
        } catch (ScoreException e) {
            System.out.println("发生exception: " + e.getMessage());
        }
    }
}

5. exceptionprocessing best practices

  • 只捕获必要 exception: 不要捕获所 has exception, 应该只捕获你able toprocessing exception.
  • using具体 exceptionclass型: 尽量using具体 exceptionclass型, 而不 is 笼统 Exception.
  • 及时释放resource: usingtry-with-resources or finally块来确保resource 释放.
  • providing has 意义 exceptioninformation: in 抛出exception时, providing清晰, has 意义 errorinformation.
  • 不要ignoreexception: 即使你不知道such as何processingexception, 也不应该空catch块.
  • 合理using受检exception and 非受检exception: for 于程序可以restore exception, using受检exception; for 于程序无法restore exception, using非受检exception.

实践case: exceptionprocessing in fileoperationin application

in fileoperationin, exceptionprocessing is 非常 important , 因 for fileoperation可能会遇 to 各种exceptioncircumstances, such asfile不存 in , permission不足etc..

import java.io.*;

public class FileOperationExample {
    public static void readFile(String filePath) {
        // usingtry-with-resources自动关闭resource
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            System.out.println("file读取成功!");
        } catch (FileNotFoundException e) {
            System.out.println("error: file不存 in  - " + e.getMessage());
        } catch (IOException e) {
            System.out.println("error: IOexception - " + e.getMessage());
        } catch (Exception e) {
            System.out.println("error: 未知exception - " + e.getMessage());
        }
    }
    
    public static void writeFile(String filePath, String content) {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
            writer.write(content);
            System.out.println("file写入成功!");
        } catch (IOException e) {
            System.out.println("error: IOexception - " + e.getMessage());
        }
    }
    
    public static void main(String[] args) {
        // testfile读取
        System.out.println("=== testfile读取 ===");
        readFile("existing.txt");
        readFile("non_existing.txt");
        
        // testfile写入
        System.out.println("\n=== testfile写入 ===");
        writeFile("output.txt", "Hello, World!\nThis is a test file.");
    }
}

这个example展示了such as何 in fileoperationinusingexceptionprocessing:

  1. usingtry-with-resources自动关闭resource
  2. 捕获具体 exceptionclass型并providing has 意义 errorinformation
  3. using many 层catch块processing不同class型 exception

互动练习

练习1: implementation一个exceptionprocessing 计算器

writing一个Java计算器程序, implementationbasic 算术运算, 并processing可能 exceptioncircumstances.

要求:

  1. implementation加, 减, 乘, 除四种运算
  2. processing除数 for 零 exception
  3. processing输入非number exception
  4. providing友 good error提示information

练习2: 自定义exception

writing一个Java程序, implementation一个学生managementsystem, package含自定义exception.

要求:

  1. creation一个自定义exceptionclassStudentException
  2. implementation添加学生 method, 当学生年龄不符合要求时抛出exception
  3. implementationquery学生 method, 当学生不存 in 时抛出exception
  4. in 主methodintest这些functions, 捕获并processingexception

练习3: exceptionprocessing in networkprogrammingin application

writing一个Java程序, implementation一个 simple network客户端, processing可能 networkexception.

要求:

  1. creation一个TCP客户端, 连接 to 指定 server
  2. processing连接超时 exception
  3. processingnetwork不可达 exception
  4. providing友 good error提示information
  • 便于debug and maintenancecode
  • exception层次structure

    Javain 所 has exception都 is Throwableclass 子class, Throwable has 两个直接子class: Error and Exception.

    1. Error

    Error表示严重 error, 通常 is 程序无法restore circumstances, such asOutOfMemoryError, StackOverflowErroretc.. 这些error通常由JVM抛出, 程序不应该尝试捕获 and processing它们.

    2. Exception

    Exception表示程序可以processing exception, 它又分 for 两 big class:

    // exception层次structureexample
    Throwable
    ├── Error
    │   ├── OutOfMemoryError
    │   ├── StackOverflowError
    │   └── ...
    └── Exception
        ├── RuntimeException (非受检exception)
        │   ├── NullPointerException
        │   ├── ArrayIndexOutOfBoundsException
        │   ├── ArithmeticException
        │   └── ...
        └── otherexception (受检exception)
            ├── IOException
            ├── SQLException
            ├── ClassNotFoundException
            └── ...

    try-catch-finally语句

    try-catch-finally语句 is Javainprocessingexception basicstructure:

    1. try块

    try块package含可能抛出exception code.

    2. catch块

    catch块用于捕获 and processingtry块in抛出 exception. 一个try块可以 has many 个catch块, 分别processing不同class型 exception.

    3. finally块

    finally块package含无论 is 否发生exception都需要执行 code, 通常用于resourcecleanoperation, such as关闭file, datalibrary连接etc..

    // try-catch-finallybasicstructure
    try {
        // 可能抛出exception code
        System.out.println("尝试执行可能出错 operation");
        int result = 10 / 0; // 会抛出ArithmeticException
    } catch (ArithmeticException e) {
        // 捕获并processingArithmeticException
        System.out.println("捕获 to 算术exception: " + e.getMessage());
    } catch (Exception e) {
        // 捕获并processingother所 has exception
        System.out.println("捕获 to otherexception: " + e.getMessage());
    } finally {
        // 无论 is 否发生exception都会执行 code
        System.out.println("finally块执行, 用于resourceclean");
    }

    many 个catch块 顺序

    当using many 个catch块时, exceptionclass型 顺序很 important . 应该先捕获更具体 exceptionclass型, after 捕获更common exceptionclass型.

    // 正确 catch块顺序
    try {
        // 可能抛出exception code
        FileReader reader = new FileReader("test.txt");
        int result = 10 / 0;
    } catch (FileNotFoundException e) {
        // 先捕获具体 FileNotFoundException
        System.out.println("file未找 to : " + e.getMessage());
    } catch (ArithmeticException e) {
        // 再捕获具体 ArithmeticException
        System.out.println("算术exception: " + e.getMessage());
    } catch (Exception e) {
        // 最 after 捕获common Exception
        System.out.println("otherexception: " + e.getMessage());
    } finally {
        System.out.println("执行finally块");
    }

    throws and throw关键字

    1. throws关键字

    throws关键字用于声明method可能抛出 exception, 它出现 in methodsignature 末尾. 当methodusingthrows声明exception时, 调用该method code必须processing这些exception, or 者继续usingthrows声明将exception向 on 传播.

    // usingthrows声明exception
    public void readFile(String fileName) throws FileNotFoundException {
        FileReader reader = new FileReader(fileName);
        // 读取fileoperation
    }
    
    // 调用者必须processing or 继续声明exception
    public void processFile() {
        try {
            readFile("test.txt");
        } catch (FileNotFoundException e) {
            System.out.println("file未找 to : " + e.getMessage());
        }
    }
    
    // 继续声明exception
    public void anotherMethod() throws FileNotFoundException {
        readFile("test.txt");
    }

    2. throw关键字

    throw关键字用于手动抛出exception, 它可以抛出一个已 has exceptionobject, 也可以抛出一个 new creation exceptionobject.

    // usingthrow抛出exception
    public void checkAge(int age) {
        if (age < 0) {
            throw new IllegalArgumentException("年龄不能 for 负数");
        }
        System.out.println("年龄 has 效: " + age);
    }
    
    public static void main(String[] args) {
        try {
            checkAge(-5);
        } catch (IllegalArgumentException e) {
            System.out.println("捕获 to exception: " + e.getMessage());
        }
    }

    自定义exception

    in Javain, 我们可以throughinheritanceExceptionclass or 其子class来creation自定义exception. 自定义exception通常用于表示application程序特 has errorcircumstances.

    creation自定义exception

    // 自定义受检exception
    public class InsufficientFundsException extends Exception {
        private double amount;
        
        public InsufficientFundsException(double amount) {
            super("余额不足, 需要: " + amount);
            this.amount = amount;
        }
        
        public double getAmount() {
            return amount;
        }
    }
    
    // 自定义非受检exception
    public class InvalidUserException extends RuntimeException {
        public InvalidUserException(String message) {
            super(message);
        }
    }
    
    // using自定义exception
    public class BankAccount {
        private double balance;
        
        public BankAccount(double initialBalance) {
            this.balance = initialBalance;
        }
        
        public void withdraw(double amount) throws InsufficientFundsException {
            if (amount > balance) {
                throw new InsufficientFundsException(amount - balance);
            }
            balance -= amount;
            System.out.println("取款成功, 余额: " + balance);
        }
        
        public static void main(String[] args) {
            BankAccount account = new BankAccount(1000);
            
            try {
                account.withdraw(1500);
            } catch (InsufficientFundsException e) {
                System.out.println("捕获 to 自定义exception: " + e.getMessage());
                System.out.println("差额: " + e.getAmount());
            }
            
            // 抛出非受检自定义exception
            throw new InvalidUserException("无效 user");
        }
    }

    exceptionprocessingbest practices

    try-with-resources语句

    try-with-resources语句 is Java 7引入 语法糖, 用于自动关闭implementation了AutoCloseableinterface resource.

    // usingtry-with-resources语句
    try (FileReader reader = new FileReader("test.txt");
         BufferedReader br = new BufferedReader(reader)) {
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
    } catch (IOException e) {
        System.out.println("读取file时发生exception: " + e.getMessage());
    }
    // 不需要 in finally块in关闭resource, try-with-resources会自动关闭

    实践case

    file读取exceptionprocessing

    本caseimplementation一个file读取toolclass, usingexceptionprocessingmechanismprocessing各种file读取过程in可能出现 exceptioncircumstances.

    import java.io.*;
    import java.util.ArrayList;
    import java.util.List;
    
    public class FileReaderUtil {
        /**
         * 读取file in 容并返回 for stringlist
         * @param filePath filepath
         * @return file in 容 stringlist
         * @throws FileNotFoundException such as果file不存 in 
         * @throws IOException such as果读取file时发生IOerror
         */
        public static List readFileToList(String filePath) throws FileNotFoundException, IOException {
            List lines = new ArrayList<>();
            
            // usingtry-with-resources自动关闭resource
            try (FileReader reader = new FileReader(filePath);
                 BufferedReader br = new BufferedReader(reader)) {
                
                String line;
                while ((line = br.readLine()) != null) {
                    lines.add(line);
                }
            }
            
            return lines;
        }
        
        /**
         * security地读取file in 容, processing所 has exception
         * @param filePath filepath
         * @return file in 容 stringlist, such as果发生exception则返回空list
         */
        public static List safelyReadFileToList(String filePath) {
            List lines = new ArrayList<>();
            
            try {
                lines = readFileToList(filePath);
            } catch (FileNotFoundException e) {
                System.err.println("error: file不存 in  - " + filePath);
                e.printStackTrace();
            } catch (IOException e) {
                System.err.println("error: 读取file时发生IOexception");
                e.printStackTrace();
            } catch (Exception e) {
                System.err.println("error: 发生未知exception");
                e.printStackTrace();
            }
            
            return lines;
        }
        
        public static void main(String[] args) {
            // testmethod1: 需要调用者processingexception
            System.out.println("=== testmethod1: 需要调用者processingexception ===");
            try {
                List lines1 = readFileToList("test.txt");
                System.out.println("file in 容行数: " + lines1.size());
                for (String line : lines1) {
                    System.out.println(line);
                }
            } catch (FileNotFoundException e) {
                System.out.println("捕获 to file未找 to exception: " + e.getMessage());
            } catch (IOException e) {
                System.out.println("捕获 to IOexception: " + e.getMessage());
            }
            
            // testmethod2:  in 部processing所 has exception
            System.out.println("\n=== testmethod2:  in 部processing所 has exception ===");
            List lines2 = safelyReadFileToList("nonexistent.txt");
            System.out.println("file in 容行数: " + lines2.size());
        }
    }

    互动练习

    练习1: basicexceptionprocessing

    writing一个程序, 要求user输入两个整数, 然 after 计算它们 商. usingtry-catch语句捕获可能出现 exception, such as输入非number字符 (NumberFormatException) or 除数 for 零 (ArithmeticException) .

    练习2: try-with-resources语句

    usingtry-with-resources语句writing一个程序, 读取一个文本file in 容并打印 to 控制台. 确保正确processing可能出现 IOException.

    练习3: 自定义exception

    creation一个自定义exceptionclassInvalidScoreException, 用于表示无效 考试分数. 然 after writing一个学生class, 其inpackage含设置分数 method, 当分数不 in 0-100范围 in 时, 抛出InvalidScoreExceptionexception.

    练习4: exceptionprocessingbest practices

    analysis以 under codein exceptionprocessingissues, 并forimprovement:

    public void processData(String fileName) {
        try {
            FileReader fr = new FileReader(fileName);
            BufferedReader br = new BufferedReader(fr);
            String line = br.readLine();
            int value = Integer.parseInt(line);
            System.out.println("processing结果: " + (value * 2));
            br.close();
            fr.close();
        } catch (Exception e) {
            System.out.println("出错了");
        }
    }