2020/08/22 QQ1017871939 小白学习编译时异常处理

本文介绍了Java中异常处理的关键字try, catch, finally, throws, throw的用法,强调了基类异常捕获的顺序和finally块的重要性。文章通过实例解释了手动抛出异常的场景,以及如何声明和自定义异常,帮助初学者理解Java异常处理机制。" 107563779,5736932,Android Studio 3.0 解决注解报错,"['Android开发', 'Android Studio', '注解']

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

     异常中的编译时异常

编译时异常
除了RuntimeException 以外其它的异常称为checked exception(检测异常、受检异常) ,必须捕获的异常,进行处理;不捕获程序会报错。

为什么会产生异常?下图数产生异常的缘由
在这里插入图片描述

**

Java中常见异常处理:所用到的五大关键字分别是 try catch finally throws throw

**

在这里插入图片描述

try :捕获异常的第一步是用try{…}语句块选定捕获异常的范围,将可能出现异常的代码放在try语句块中。

catch (Exceptiontype e):在catch语句块中是对异常对象进行处理的代码。每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。如果明确知道产生的是何种异常,可以用该异常类作为catch的参数;也可以用其父类作为catch的参数。
与其它对象一样,可以访问一个异常对象的成员变量或调用它的方法。
getMessage()方法,用来得到有关异常事件的信息
printStackTrace()用来跟踪异常事件发生时执行堆栈的内容。

finally:不论在try、catch代码块中是否发生了异常事件,finally块中的语句都会被执行。finally语句是可选的

**注意事项!!!

第一点:try、catch、finally三个语句块均不能单独使用,三者可以组成 try…catch…finally、try…catch、try…finally三种结构,catch语句可以有一个或多个,finally语句最多一个;

第二点:try、catch、finally三个代码块中变量的作用域为代码块内部,分别独立而不能相互访问。如果要在三个块中都可以访问,则需要将变量定义到这些块的外面;

多个catch块时候,只会匹配其中一个异常类并执行catch块代码,而不会再执行别的catch块,并且匹配catch语句的顺序是由上到下;**

一个Catch语句块的时候
在这里插入图片描述

多个catch语句块的时候
在这里插入图片描述

当try语句有多个异常语句,只会执行先到的异常语句,后面的不执行。只会匹配其中一个异常类并执行catch块代码,而不会再执行别的catch块,并且匹配catch语句的顺序是由上到下;

用图片对比:
getMessage()方法,用来得到有关异常事件的信息
printStackTrace()用来跟踪异常事件发生时执行堆栈的内容。

在这里插入图片描述

有finally语句块执行结果
在这里插入图片描述

没有finnal语句块执行结果
在这里插入图片描述

好奇的同学们会不会觉得有没有finally语句块最后还是执行,要finally语句块干什么,会显得多次一举对吧。那你在思考的这个问题的时候有没有想过如果没有finally语句块后面会出现不能执行的情况吗?如果有是什么情况?
第一种情况是当我们catch里面还有异常的时候就会出现try…catch 外面的system输出语句不执行
在这里插入图片描述
第二种是system.exit()释放资源语句,也可以称为断电。
在这里插入图片描述
在这里插入图片描述

体现有finally语句的好处。
在这里插入图片描述
**

基类异常的捕获语句不能写在子类捕获语句的前面;

**
在这里插入图片描述
在这里插入图片描述

@Test
	public void test1() {
		int a = 100;
		int b = 0;
		
		try {
			int[] i = new int[] {1,2,3,4,5,6};
			// java.lang.ArrayIndexOutOfBoundsException: 9
			System.out.println(i[1]); // 抛出了一个异常对象(实例)
			
			
			
			// java.lang.ArithmeticException: / by zero
			System.out.println(a/b);
			
			System.out.println("方法没有异常,结束调用了...");
			
			// Exception
			
		}catch(ArrayIndexOutOfBoundsException e) {
			
			System.out.println("出现了数组下标越界异常:"+e.getMessage());
			// 在控制台打印异常信息:栈结构,表现的就是方法的调用关系
			e.printStackTrace();
			System.out.println(a);
			
		}catch(NullPointerException e) {
			System.out.println("出现了空指针异常:"+e.getMessage());
			
		}catch(ArithmeticException e) {
			System.out.println("出现了算术异常:"+e.getMessage());
			
			/*try {
				String s = null;
				System.out.println(s.lastIndexOf(11));
			}catch(NullPointerException e1) {
				
			}*/
			
		}finally {
			// finally中的代码是一定要执行的
			System.out.println("finally ... ");
		}
		// 写在最后的代码和finally中的情况,是不同的,有可能不执行
		//System.out.println("最后要执行的代码 ... ");
		
	}

try/catch/finally中return
在这里插入图片描述

在这里插入图片描述

当我在finally代码里面添加return 3结果会输出什么?是finally代码 然后3 然后 1?
在这里插入图片描述

正确答案是是finally代码 然后3 当我return 3 的时候已经返回了,就不需要再到return 1 那里。那么接下来你自己动手写一下代码

package yichangchuli;

public class Yichang4 {
 public int test() {
	 //这是正常运行
	try {
		int a =10;
		int b= 1;
		int c=a/b;
		return 1;// 方法在这里要结束了,查找有没有finally,如果有,马上执行finally,再return
		
	} catch (ArithmeticException e) {
		e.printStackTrace();
		return 2;
	}finally {
		System.out.println("finall代码");
	 return 3;
	}
	 
	 
 }
 
 public static void main(String[] args) {
	 Yichang4 tc1 =new Yichang4();
	 int num =tc1.test();
	 System.out.println(num);

}
}

异常里面也可以重载:规则:重写方法需要抛出与原方法所抛出异常类型一致或不抛出,(此规则不包括非检测异常)
在这里插入图片描述

package yichangchuli;

import java.io.IOException;

public class Yichang5 {
	//重写方法声明抛出异常规则不包括非检测异常
    public void m() throws IOException{}
    
    class B extends Yichang5{
    	//重写方法与原方法一致
    	public void m() throws IOException{}
    	
    }
    class c extends Yichang5{
    	//错误的写法
//    	public void m() throws Exception{}
    }
    class D extends Yichang5{
    	//或者不抛出
    	public void m() {};
    }
}

在这里插入图片描述

声明抛出异常:处理异常的第二种方式

如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显式地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。

在方法声明中用 throws 子句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。

声明抛出异常举例:

  public void readFile(String file) throws FileNotFoundException {
	......
	// 读文件的操作可能产生FileNotFoundException类型的异常
	FileInputStream fis = new FileInputStream(file);
	......
 }

在这里插入图片描述

package yichangchuli;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;

public class Yichang6 {
	// throws关键字,在方法的声明处,显示的告知方法的调用者,该方法可能会抛出什么异常。
	//多个异常可以用逗号分隔开
   public Connection  getConn() throws ClassNotFoundException,SQLException{
	   
//		  Connection conn = DriverManager .getConnection("jdbc:mysql://localhost:3306/test","root","123456");
		  //其实上面那段话相当于等价的意思
		  return DriverManager .getConnection("jdbc:mysql://localhost:3306/test","root","123456");
		 
	  
	   
   }
}

在这里插入图片描述
在这里插入图片描述

**

如何理解手动抛出异常呢?其实手动抛出异常也就是比如相当于你去电信营业厅换手机卡,客服说对不起,我们这里不能给你解决,这时候客服会推荐去更高级的营业厅去办理,其实手动抛出异常就像这样。

**

自定义异常:当JDK中的异常类型不能满足程序的需求的时候,可以自定义异常类。使用自定义异常类的步骤:
定义异常类,并继承Exception或者RuntimeException;
编写异常类的构造方法,并继承父类的实现;

首先我们得先写一个类,自定义异常的类去继承我们的父类Exception
在这里插入图片描述

如果你能联想的话就会想明白那些什么数组下标越界异常、还有转换类型异常里面的源代码也是继承我们的父类。但是为什么要写那么多子类异常呢,其实就是想自定义遇到不同异常具体报告,方便我们好查找。

package com.zidingyi;

public class ZidingyiException extends Exception{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public ZidingyiException() {
		super();
	
	}

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

然后我们新建一个类是我们设置匹配,就比如我们从那边登录输入了信息,就传到我这个类去判断一下,判断输入和我们的账号密码不匹配就给你报错,爆我们自定义的异常
在这里插入图片描述

package com.zidingyi;

public class LoginException {
   //使用自定义异常 登录失败的话就抛出一个自定义异常
	public String login(String username,String password) throws ZidingyiException {
		if(username ==null ||password==null ||username==""||password=="") {
		  //如果名字为空或者密码为空或者输入空格
		throw new ZidingyiException("用户名或密码都不能为空");
	}//如果等于我们的账号admin  密码123456  则登录成功
	if(username.equals("admin") && password.equals("123456")) {
		return "登录成功";
	}else {
		throw new ZidingyiException("登录失败");
	}
}
}

最后就是我们用户输入的账号和密码了

在这里插入图片描述

package com.zidingyi;

public class Loginusername {
    public void login(String username,String password) {
    	LoginException t1 =new LoginException();
    
		String msg;
		try {
			msg = t1.login(username, password);
			System.out.println("恭喜你!"+msg);
		} catch (ZidingyiException e) {
			e.printStackTrace();
		}
		
    }
    public static void main(String[] args) {
    	Loginusername um =new Loginusername();
     	um.login("admin", "123456");  //登录成功
    	//um.login("abc", "123456");
	}
}
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值