Java中的异常处理

本文详细介绍了Java中的异常处理机制,包括异常的概念、分类及其处理方式。重点解释了检查性异常、运行期异常和错误的区别,并通过示例展示了如何使用try...catch及finally语句进行异常的捕获和处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概念

Java中的异常是指在程序编译、运行中产生的异常状况,使得程序无法正常输出结果。

二、分类

按照异常出现的时间节点,可以将其分为:

(1)检查性异常:Java.lang.Exception

(2)运行期异常:Java.lang.RuntimeException

(3)错误:Java.lang.Error

     以上三个类的 Java.lang.Throwable是的子孙类,其中Java.lang.Exception,Java.lang.Error是Java.lang.Throwable的子类,而Java.lang.RuntimeException则是Java.lang.Exception的子类。具体如下图


三、深入理解

检查性异常:程序的逻辑正确,但是由于外部的环境条件无法满足引发的异常。例如:I/O问题,程序试图打开一个不存在的文件,或者连接一个不存在的IP,都会报出此类错误。Java程序强制要求处理这类错误,如果不捕获这些异常,程序将无法编译。

举个例子:

import java.io.FileReader;
import java.net.Socket;

public class Test3 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//1.打开一个不存在的文件
		FileReader fr=new FileReader("d:\\aa.txt");  //报错:FileNotFoundException
		
		//2.连接一个不存在的IP
		Socket ss = new Socket("192.168.170.55",220);   //报错: IOException

	}
}

注意:此处的两个错误,不是说就一定有FileNotFound,或者没有"192.168.170.55",220 这个端口,而是说“可能存在这样的错误”,因此要抛出异常,对其处理。而且事实上我的d:/下面是有aa.txt文件的。

运行期异常:是程序存在bug,例如0被除,数组越界,传入的参数不满足规范等。Java程序强制要求处理这类异常。

错误(Error):一般很少见,它可能源于程序的bug,但更可能是程序的环境问题,例如内存耗尽等,这类异常在程序中无需处理,又运行环境决定。(当然也可以尝试修改 程序启动时的初始内存大小)


四、异常的处理

1、在异常的发生地,直接 try ……  catch……

看栗子1:

import java.io.FileReader;
import java.io.IOException;
import java.net.Socket;

public class Test3 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//2.连接一个不存在的IP
		try {
			Socket ss = new Socket("192.168.170.55",220);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("OK");
	}
}

在前面的Code中,直接对IOException进行了捕获。

输出

java.net.UnknownHostException: 192.1688.170.55
	at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
	at java.net.PlainSocketImpl.connect(Unknown Source)
	at java.net.SocksSocketImpl.connect(Unknown Source)
	at java.net.Socket.connect(Unknown Source)
	at java.net.Socket.connect(Unknown Source)
	at java.net.Socket.<init>(Unknown Source)
	at java.net.Socket.<init>(Unknown Source)
	at demo.Test3.main(Test3.java:12)
OK
在查询后确认没有找到该主机后报出UnknownHostException() ,而且最后打印出OK。

再看例子2:

public class Test3 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//1.打开一个不存在的文件
		try {
			FileReader fr=new FileReader("d:\\abc.txt");
			Socket ss = new Socket("192.1688.170.55",220);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  catch(IOException e2){
			e2.printStackTrace();
		}
		
		System.out.println("OK");
	}
}
输出:

java.io.FileNotFoundException: d:\abc.txt (系统找不到指定的文件。)
	at java.io.FileInputStream.open0(Native Method)
	at java.io.FileInputStream.open(Unknown Source)
	at java.io.FileInputStream.<init>(Unknown Source)
	at java.io.FileInputStream.<init>(Unknown Source)
	at java.io.FileReader.<init>(Unknown Source)
	at demo.Test3.main(Test3.java:13)
OK
可以看到,程序报出FileNotFoundException 之后就没有再执行 Socket ss = new Socket("192.1688.170.55",220); ,而是直接跳出了try……catch……语句,进入到了下一句

2、finally语句块

   一般是把finally 语句块放在try……catch……之后,在finally 语句块中写入必须要执行的代码,相当于上了一个万能险,在catch出现异常而catch 又没有捕获时,finally将马上执行。

栗子:

public class Test3 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		FileReader fr=null;
		//1.打开一个不存在的文件
		try {
			 fr=new FileReader("d:\\aa.txt");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  finally{
			try {
				fr.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				System.out.println("在关闭文件aa.txt时出现错误!");
			}
		}
		
		System.out.println("OK");
	}
}

在上面的code中,加入finally语句块,fr.close 来关闭 aa文件。

而且无论前面 try ……catch……中是否出现异常,finally语句块都会执行。


注意:以下情况下finally语句块无法执行

(1)finally语句块中出现异常

(2)程序所在的线程死亡

(3)前面的代码中出现System.exit()

(4)关闭CPU

3、throws 语句








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值