java的异常处理

本文深入讲解Java中的异常处理机制,包括异常分类、抛出、捕获及自定义异常。探讨了运行时异常与检查异常的区别,以及如何在代码中正确处理异常。

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

复习java基础,异常类和异常处理

一、异常分类

    java的一切异常和错误都是继承Throwable,Throwable下两个子类ErrorException,Error一般为系统内部错误,我们处理不了,由系统处理。我们关注的是Exception,Exception是我们能够处理的异常,这些异常往往是由于我们编码出问题或者操作引起的异常。
    

Exception下有很多子异常,可以分为两大类RuntimeException(运行时异常 也叫非检查异常)和其他各种异常(非运行异常 也叫检查异常)。

Object
Throwable
Error
Exception
IOException
RuntimeException
RuntimeExcption 异常(运行时异常)通常有以下几种:
  1. 空指针异常(NullPointerException)
  2. 类型转换异常(ClassCastException)
  3. 数组下标越界异常(ArrayIndexOutOfBoundException)
  4. 算术异常(ArithmeticException)

    一般来说,RuntimeException 一般都是代码有问题,逻辑有错。这些异常在编译时并不会报错,可以捕获,也可以不捕获的异常,会由JVM(java虚拟机)自动抛出自动捕获。
编译时异常,一般都是IOException或SQLException等
  1. 打开一个不存在的文件
  2. 没有找到具有指定名称的类
  3. 操作文件异常
  4. 连接错误
  5. sql错误

非运行时异常,是检查异常。受查异常是编译器要求必须处理的异常,必须使用 try catch 处理,或者向上抛出,给上层处理。否则编译时会报错。(强调区别)

二、抛出异常

异常抛出

异常抛出的语法是

throw new 异常名();

在add方法里,抛出了个RuntimeException的子类NullPointerException

package test;

public class ThrowTest {
 
	public static void main(String[] args) {		
		add(1,null);//调用方法		
	}
	
	public static Integer add(Integer a,Integer b){	
		if(a == null || b == null){//抛出异常
		  throw new NullPointerException("相加的Interger值不能为空");
		}else{
			return a + b;
		}
		
	}
		
}

运行结果

Exception in thread "main" java.lang.NullPointerException: 相加的Interger值不能为空
	at test.ThrowTest.add(ThrowTest.java:15)
	at test.ThrowTest.main(ThrowTest.java:8)

NullPointerException是运行时异常,注意没有在方法头抛出也没有去捕获,能编译通过没报错,上面说过运行时异常可捕获和不捕获,运行时JVM自动抛出和捕获。

throws 声明异常

throws 用于声明异常,表示该方法可能会抛出的异常。如果声明的异常中包括 checked 异常(受查异常),那么调用者必须处理该异常或者使用 throws 继续向上抛出。throws 位于方法体前,多个异常使用,分割。

三、异常捕获

捕获异常的语法是

try{
		//可能抛出异常的代码块
		}catch(Exception e){//捕获异常	
						
		}fianlly{
		
		}

try是必有的,而catch和fianlly是可选的,catch是捕获异常后的处理,fianlly里是不管异常是否发生都会执行里面的语句

package test;

public class ThrowTest {
 
	public static void main(String[] args) {
		try{
		int num  = add(1,null);//调用方法
		System.out.println(num);
		}catch(NullPointerException e){
			
		}
	}
	
	public static Integer add(Integer a,Integer b) throws NullPointerException{//方法头声明抛出的异常
		if(a == null || b == null){//抛出异常
		  throw new NullPointerException("相加的Interger值不能为空");
		}else{
			return a + b;
		}
		
	}
		
}


1.上面我用catch捕获了异常但不做处理

运行后,控制台不报异常,没有输出,因为我们捕获了却不做处理

2.如果catch里加了输出

catch(NullPointerException e){
	System.out.println("ERROR加法出了问题:"+e.getMessage());
		}

运行后控制台的输出:

加法出了问题:相加的Interger值不能为空

3.如果catch里加了e.printStackTrace();

catch(NullPointerException e){
			System.out.println("ERROR加法出了问题:"+e.getMessage());
             e.printStackTrace();
		}

控制台输出

ERROR加法出了问题:相加的Interger值不能为空
java.lang.NullPointerException: 相加的Interger值不能为空
	at test.ThrowTest.add(ThrowTest.java:18)
	at test.ThrowTest.main(ThrowTest.java:7)

可见 e.printStackTrace();的作用是输出异常的轨迹,这异常堆栈轨迹,方便我们找到异常。

一个try可以有多个catch

public static void main(String[] args) {
		try{//捕获处理
			TestTwo();		
		}catch(NullPointerException e){
			System.out.println("捕获了空子针异常");
             e.printStackTrace();
		}catch(RuntimeException e){
			System.out.println("捕获了运行时异常");
			 e.printStackTrace();
		}catch(IOException e){
			System.out.println("捕获了IO异常");
			 e.printStackTrace();
		}catch(Exception e){
			System.out.println("捕获了未知异常");
			 e.printStackTrace();
		}
		
	}

注意:
1.当匹配到对应的异常后,后面的异常将不再进行匹配。
2.而且也不要求完全匹配,如果是子类的异常,其父类可以到匹配,像Exception可以匹配任何异常。
所以如果多个catch,有子父异常,子异常一定要放在前面,像先catch NullPointerException 再catch RuntimeException, 否则会报错。(原因也很简单,如果父类 RuntimeException在前面,他会先匹配了,其子类在后面永远也执行不到)

如果抛出的是受检查异常(非运行异常)
必须try,catch处理,如果不处理则要继续抛出由上层处理,否则报错(强调和运行时异常的区别)

package test;

import java.io.IOException;

public class ThrowTest {
 
	public static void main(String[] args) {
		try{//捕获处理
			TestTwo();		
		}catch(Exception e){
             e.printStackTrace();
		}
	}

//方法TestTwo调用方法testOne,受检查异常要捕获异常或者继续抛出交由上层处理,否则会报错
public static void TestTwo()throws IOException{	//继续抛出
		
	 TestOne();
		  
  }	

//方法testOne声明了可能抛出的异常
public static void TestOne()throws IOException,NullPointerException{
		if( 1 == 1)
		  throw new IOException();	//抛出了受检查异常
		else{
			throw new NullPointerException();
		}
    }
	
}

四、自定义异常

如果在开发自己的项目,不免要自定义异常类型。
简单定义一个异常,继承RuntimeException,当然也可以继承Exception.但是在spring里的事务只支持对RuntimeException的回滚

package test;

public class IsNullException extends RuntimeException{

	public IsNullException() {
		super();		
	}

	public IsNullException(String message) {
		super(message);		
	}
	
}

抛出并捕获

package test;

public class ThrowTest {
 
	public static void main(String[] args) {
		try{//捕获处理
			Add(1,null)	;
		}catch(Exception e){//捕获异常
         e.printStackTrace();
		}
	}

   public static Integer Add (Integer a,Integer b){
	   if(a == null || b == null){
	   throw new IsNullException("加数不能为空");//抛出自定义异常
	   }
	   else{
		   return a+b;
	   }
   }

	
}

还可以依靠异常处理来做很多东西
。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值