java异常处理

一、异常的概念总结

  1. 异常的定义

    • 在Java语言中,异常指的是程序运行过程中遇到的意外情况,例如错误的输入、网络断开、文件不存在等。处理这些异常情况称为异常处理。
  2. Throwable类

    • 所有异常和错误都继承自 Throwable 类。它是 Java 异常体系的根类。
  3. Throwable的两大分支

    • Error:代表严重的错误,通常由系统和虚拟机发出,程序无法恢复,比如内存溢出、虚拟机错误等。
    • Exception:代表程序运行中的异常情况,分为运行时异常和检查时异常。
  4. 异常的处理

    • 运行时异常(RuntimeException):编译时可以不强制处理,通常由程序员的逻辑错误引起,如空指针异常(NullPointerException)、数组越界异常(ArrayIndexOutOfBoundsException)、算术异常(ArithmeticException)等。
    • 检查时异常(Checked Exception):编译时必须处理或声明抛出,如文件找不到(FileNotFoundException)、IO异常(IOException)、数据库异常(SQLException)等。
  5. 异常处理的应用

    • 对于运行时异常,程序员可以选择处理或不处理,但建议进行逻辑判断避免异常发生。
    • 对于检查时异常,必须在编译时处理或声明抛出,确保程序在可能发生异常的情况下有所准备。
  6. 示例说明:

public class ExceptionHandlingExample {

    public static void main(String[] args) {
        try {
            int[] array = new int[3];
            System.out.println(array[4]); // 可能抛出 ArrayIndexOutOfBoundsException
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组越界异常:" + e.getMessage());
        }

        try {
            FileReader file = new FileReader("file.txt"); // 可能抛出 FileNotFoundException
        } catch (FileNotFoundException e) {
            System.out.println("文件未找到异常:" + e.getMessage());
        }
    }
}

在上面的示例中,第一个 try-catch 块处理了数组越界异常,第二个 try-catch 块处理了文件未找到异常。这展示了如何针对不同类型的异常进行处理,以确保程序的健壮性和稳定性。

这些总结可以帮助程序员更好地理解和应用异常处理机制,在开发过程中有效地预防和处理各种异常情况。

1. 继承关系

在Java中,异常处理体系主要分为两大类:ErrorException。下面给出了你列出的异常类的继承关系:

Throwable
├── Error
│   ├── AssertionError
│   ├── OutOfMemoryError
│   ├── IOError
│   └── VirtualMachineError
│       ├── StackOverflowError
│       └── ... (其他虚拟机相关错误)
└── Exception
    ├── RuntimeException
    │   ├── NullPointerException
    │   ├── IndexOutOfBoundsException
    │   │   ├── ArrayIndexOutOfBoundsException
    │   │   └── StringIndexOutOfBoundsException
    │   ├── IllegalArgumentException
    │   ├── IllegalStateException
    │   ├── UnsupportedOperationException
    │   └── ... (其他运行时异常)
    └── IOException
        ├── FileNotFoundException
        ├── EOFException
        └── ... (其他IO异常)
  1. Error 类及其子类:

    • Error
      • OutOfMemoryError:当JVM无法分配更多内存时抛出。
      • VirtualMachineError:指示JVM遇到了严重错误,可能需要终止。
      • LinkageError:子类,当类或方法在链接阶段出现问题时抛出。
        • NoClassDefFoundError:当类在初始化时找不到其依赖的类的定义时抛出。
        • IncompatibleClassChangeError:当一个类的静态类型和动态类型不兼容时抛出。
        • UnsatisfiedLinkError:当尝试加载一个不存在或不可访问的本地库时抛出。
    • ThreadDeath:当线程结束时抛出。
    • StackOverflowError:当程序栈溢出时抛出。
    • IOException:实际上不是Error的子类,而是Exception的子类。
  2. Exception 类及其子类:

    • Exception
      • RuntimeException:在运行时抛出的异常,通常是由编程错误引起的。
        • NullPointerException:当应用试图使用null引用时抛出。
        • ArrayStoreException:当试图向数组中存储不兼容类型的对象时抛出。
        • ClassCastException:当应用试图将对象强制转换为不兼容的类型时抛出。
        • IllegalArgumentException:当方法接收到非法参数时抛出。
        • IllegalStateException:当方法处于不适当的调用状态时抛出。
        • UnsupportedOperationException:当方法不支持请求的操作时抛出。
        • IndexOutOfBoundsException:当索引超出数组范围时抛出。
        • ArithmeticException:当算术运算遇到异常条件时抛出。
        • NumberFormatException:当字符串不能解析为数字时抛出。
        • StringIndexOutOfBoundsException:当索引超出字符串范围时抛出。
        • ConcurrentModificationException:当多线程修改集合时抛出。
        • SecurityException:当安全策略被违反时抛出。
        • NegativeArraySizeException:当数组大小为负数时抛出。
        • AssertionError:当断言失败时抛出。
      • IOException:当输入/输出操作中发生问题时抛出。
        • FileNotFoundException:当尝试读取不存在的文件时抛出。
        • EOFException:当达到流的末尾但仍有数据需要读取时抛出。
      • DOMException:在处理XML文档时抛出。
      • XMLStreamException:在处理XML流时抛出。
      • SAXException:在使用SAX解析XML时抛出。
      • ObjectStreamException:在序列化或反序列化对象时抛出。

Throwable 是所有异常和错误的顶级父类,它有两个直接子类:ErrorExceptionException 又分为 RuntimeExceptionCheckedException(例如 IOException),其中 RuntimeException 不需要在方法签名中声明,而 CheckedException 需要在调用的方法中显式捕获或声明抛出。

注意,Error 类通常表示JVM或系统级别的错误,不应该被程序捕获或处理,而应该让程序终止;Exception 类表示程序可以处理或恢复的异常情况。

2. 解释继承关系

  1. Throwable

    • Java中所有异常和错误的根类。
  2. Error

    • 表示严重的错误,一般由虚拟机抛出,程序无法处理。常见的有 AssertionError, OutOfMemoryError, StackOverflowError 等。
  3. Exception

    • 可由程序员处理的异常类。
  4. RuntimeException

    • 运行时异常,编译器不会强制要求处理的异常。常见的有 NullPointerException, IndexOutOfBoundsException, IllegalArgumentException 等。
  5. IOException

    • 输入输出异常,通常用于处理文件操作等可能出现的异常。

在继承关系中,每个异常类都继承自更具体的异常或错误类,这种继承关系使得异常处理更加灵活和结构化。

二、异常的处理

异常处理在Java中通过 try, catch, finally, throw, throws 等关键字实现,下面对它们进行简要总结:

  1. try-catch-finally

    • try:包裹可能会抛出异常的代码块。
    • catch:捕获并处理 try 块中抛出的异常。
    • finally:不论是否发生异常,都会执行的代码块,通常用于资源释放或清理操作。
  2. throw

    • throw:用于手动抛出异常对象,指定异常发生的具体情况。
  3. throws

    • throws:用于在方法声明中标识可能抛出的异常类型,告知调用方需要处理或继续抛出这些异常。

示例说明:

public class ExceptionHandlingExample {

    // 方法示例,声明可能抛出异常
    public static void method1() throws IOException {
        // 可能抛出 IOException 的代码
        FileReader fr = new FileReader("file.txt");
        // 其他操作
    }

    // 方法示例,使用 try-catch-finally 处理异常
    public static void method2() {
        try {
            // 执行可能产生异常的代码
            int result = 10 / 0; // 会抛出 ArithmeticException
        } catch (ArithmeticException e) {
            // 捕获并处理异常
            System.out.println("除数不能为0:" + e.getMessage());
        } finally {
            // 无论是否发生异常,总能执行的代码块
            System.out.println("finally 块总是执行");
        }
    }

    // 方法示例,手动抛出异常
    public static void method3(int value) {
        if (value < 0) {
            // 手动抛出异常
            throw new IllegalArgumentException("参数不能为负数");
        } else {
            System.out.println("参数值:" + value);
        }
    }

    public static void main(String[] args) {
        try {
            method1(); // 调用可能抛出 IOException 的方法,需要处理异常或声明抛出
        } catch (IOException e) {
            System.out.println("处理 IOException:" + e.getMessage());
        }

        method2(); // 调用带有 try-catch-finally 的方法

        try {
            method3(-1); // 调用可能抛出 IllegalArgumentException 的方法,捕获并处理异常
        } catch (IllegalArgumentException e) {
            System.out.println("处理 IllegalArgumentException:" + e.getMessage());
        }
    }
}

1. try代码块

将可能产生异常的代码放入try代码块中,可以由catch捕获。

try {
    // 可能会抛出异常的代码块
} catch (异常类 异常对象) {
    // 异常处理代码
}

2. catch代码块

catch代码块用于捕获try中可能会抛出的异常,可以有多个catch块,按照异常类型从小到大顺序捕获。

try {
    // 可能会抛出异常的代码块
} catch (ArithmeticException ae) {
    // 算术异常处理
} catch (ArrayIndexOutOfBoundsException ae) {
    // 数组越界异常处理
} catch (Exception e) {
    // 其他异常处理
}

3. finally代码块

finally代码块不管try语句块是否产生异常,都会在try与catch语句块后执行。

try {
	int[] i = new int[5];
    System.out.println(i[5]); // 有可能出现异常的代码,访问数组索引越界
    System.out.println(a / b); // 有可能出现异常的代码,除法运算可能除数为0
    System.out.println(s.length()); // 有可能出现异常的代码,访问字符串长度
} catch (ArithmeticException ae) {
    System.out.println("对不起,出现了算术异常,有可能除数是0");
    JOptionPane.showMessageDialog(null, "除数不能为0");
} catch (ArrayIndexOutOfBoundsException ae) {
    JOptionPane.showMessageDialog(null, "数组下标越界");
} catch (Exception e) {
    JOptionPane.showMessageDialog(null, "出现问题");
} finally {
	//最终必须执行的代码块
    System.out.println("finally语句块...");
}

4. throw手动抛出异常

使用throw语句可以手动抛出异常,通常用于在特定条件下抛出自定义异常。

class PowerNotEnoughException extends Exception
{
	//String message ="权限不足!"
	public PowerNotEnoughException(){
		//调用父类Exception的构造方法
		super("权限不足!");
	}
}
public class TestException2 {
    public static void main(String[] args) {
        String adminName = "张三1";
        try {
            if ("张三".equals(adminName)) {
                System.out.println("管理员登录");
            } else {
                // 手动抛出异常,自定义异常
                throw new PowerNotEnoughException("权限不足!");
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

5. throws在方法中声明异常

使用throws关键字在方法声明中指定可能抛出的异常,调用该方法时要求处理或继续抛出。

class A {
    public void printName() throws Exception {
        // 方法体可能抛出异常
    }
}
class B {
    public void p() throws Exception {
        A a = new A();
        a.printName(); // 调用方法时要求处理异常
    }

    public static void main(String[] args) {
        B b = new B();
        try {
            b.p();
        } catch (Exception e) {
            System.out.println("处理异常:" + e.getMessage());
        }
    }
}

6. finally与return语句

在方法中使用return语句时,先执行finally块再返回值

public class TestF {
	public static int getValue(){
		int i = 0;
		try{
			i = 10;
			//if(i >= 10) throw new Exception("ccc");
			return i;//在执行return语句时先检查有没有finally,假如没有直接return返回,
			         //有的话先把return 10;压入栈中再执行finally,执行完毕,再把return语句出栈执行   
		}catch(Exception e){	
		}finally{
			i = 20;
			System.out.println("finally");
		}
		return i;//必须保证该方法一定要有返回值
	}
	public static void main(String[] args){
		System.out.println(getValue());
	}

    ---------- 输出结果 ----------
	    finally
	    10
	输出完成 (耗时 0) - 正常终止

三、总结异常处理需要注意的地方

1. try、catch、finally结构

  • try语句不能单独存在,必须与catch、finally组合使用,形成以下三种结构之一:
    • try…catch…finally
    • try…catch
    • try…finally
  • catch语句可以有一个或多个,用于捕获不同类型的异常。
  • finally语句最多一个,用于无论是否发生异常都必须执行的情况。

2. 变量作用域

  • try、catch、finally三个代码块中的变量作用域独立,彼此不能直接访问。如果需要在三个块中都访问同一变量,需要将其定义在这些块的外部。

3. 多个catch块

  • 当多个catch块存在时,Java虚拟机会匹配其中一个异常类或其子类,只执行第一个匹配的catch块,而忽略其余的catch块。

4. throw后紧跟语句

  • throw语句后不能紧跟其他语句,因为在throw语句后抛出异常,紧跟的语句不会执行。

示例代码:

try {
    i = 10;
    throw new Exception("ccc");
    return i; // 编译器报错,无法执行到此处的return语句
} catch (Exception e) {
    // 异常处理代码
}

这些注意事项能帮助开发者更好地理解和使用Java中的异常处理机制,确保程序在面对异常情况时能够正确、可控地处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值