异常之(抛出和捕获、finally的使用、异常的处理机制2:throws、异常的处理机制一:try-catch-finally)
关键词: try:尝试处理什么东西 catch:捕获什么东西 finally:无论怎么要都是会执行 throws、throws:从类或方法中抛出异常 结构: try { 代码块 } catch(Exception e) { } finally { }
异常:
import java.util.Scanner; public class Main { public static void main(String[] args) { int a=1; int b=0; try {//监控区域 int c=a/b;//0作为被除数,不然会出现算术异常 System.out.println(c); } catch(Error e) {//捕获异常,当有多个异常类别的时候,我们的异常类别要从小到大开始,因为他只会生效一个,如果把异常类型从大到小写的时候,会报错 //如果出现了异常,就执行当前代码块的代码 System.out.println("Error"); }catch(Exception e) {//捕获异常 System.out.println("Exception"); }catch(Throwable e) {//捕获异常 System.out.println("Throwable"); e.printStackTrace();//打印错误的栈信息 } finally {//处理善后工作 //不管有没有出现异常都会执行 } } }
主动抛出异常:
import java.util.Scanner; public class Main { public static void main(String[] args) { //创建匿名类,调用方法 new Main().test(1,0);//方法没有使用throws ArrayStoreException方式抛出异常时就不需要用try-catch //如果方法向上抛出异常了,那我们就要用try-catch来处理异常了 try { new Main().test(1,0); } catch(Exception e) { System.out.println("向上抛出的异常处理"); } finally { } } //3.假设这方法主动抛出了异常,但是处理不了异常那我们就要向上抛出。 public void test(int a,int b)throws ArrayStoreException{ //1.当我们觉得当前的代码可以会出现异常时,那这个时候我们可以主动抛出异常 if (b==0){ //2.正常情况下,我们这个方法并没有进行计算,是不会报错的,但是我们现在呢,是提前在错误报出来了 throw new ArrayStoreException();//主动抛出异常,一般用在方法中, } } }
package 异常; import javax.management.RuntimeErrorException; import sun.awt.Symbol; public class StudTest { public static void main(String[] args) { try { Studeb ka=new Studeb(); ka.iymm(-1001); System.out.println(ka.toString()); } catch (Exception e) { // TODO Auto-generated catch block System.out.println(e.getMessage()); } } } class Studeb{ int id; public void iymm(int id) throws Exception{ if (id>0) { this.id=id; }else { // System.out.println("你的数据非法"); //手动抛出异常对象 // throw new RuntimeException("你的数据非法"); throw new Exception("你的数据非法"); } } @Override public String toString() { return "Studeb [id=" + id + "]"; } }
重点:异常的处理机制一:try-catch-finally
代码: package 异常; /* * 一、异常的处理:抓抛模型 * 过程一:“抛”:程序在正常执行过程中,一但出现 异常,就会在异常代码处,生成一个对应异常类的对象 * 并将此对象抛出。 * 一但抛出对象以后,其后的代码不再执行 * * 关于异常对象的产生:1、系统自动生成的对象 2、手动的生成一个生成的对象,并抛出throw * 过程二:“抓”:可以理解为异常的处理方式:1、try--catch-finally。 * 2、throws * * * 二、try--catch-finally的使用 * * try{ * //这里写可能会出现异常的代码,但不一定出现 * }catch(异常类型1 变量名1){ * //处理异常的方式1 * * }catch(异常类型2 变量名2){ * //处理异常的方式1 * * }catch(异常类型3 变量名3){ * //处理异常的方式1 * * } * ..... * finally{ * //一定会执行的代码 * } * * 说明: * 1、finally是可选的。 * 2、使用try将可能出现异常的代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此对象 * 的类型,去catch中进行匹配 * 3、一旦try中的异常对象匹配到某一个catch时,就会进入catch中进行异常处理,一旦处理完成,就跳出当前的try-catch结构(在没有写finally的情况下)。继续执行其后的代码 * 4、catch中的异常类型,如果没有子父类关系,则谁声明在上,谁声明在下无所谓。 * 如果catch中的异常类型满足子父类关系,则要求子类一定声明在父类的上面。否则,报错 * 5、常用的异常对象处理的方式:1、String getMessage() 2、printStackTrace(),后面那个比较常用 * 6、在try结构中声明的变量,再出了try结构以后就不能再调用,但是可以在try结构外声明好变量,然后在try中调用,注意声明的变量要初始化 。 7、try-catch-finally结构可以嵌套 * *体会1:使用try-catch-finally处理编译时异常,使得程序编译时不报错,但是运行时仍可能报错,相当于我们使用try-catch-finally将一个编译时可能出现 的异常,延迟到运行时出现 * 体会2:开发中由于运行异常比较常见,所以我们通常就不针对运行睦异常编写try-catch-finally了,针对于编译时异常一定要考虑异常的处理 */ import org.junit.Test; public class ExcptionTest1 { @Test public void test1() { String str = "123"; str = "abc"; //在try外声明变量 int num=0; try {//try内变量被调用 num = Integer.parseInt(str); System.out.println("你好"); } catch (NumberFormatException e) { // System.out.println("输入类型错误,请输入正确的类型,比如:123"); //常用的两种处理异常的方法 //String getMessage(): System.out.println(e.getMessage()); //printStakTrace(): e.printStackTrace(); } System.out.println("必执行"); //try外变量被调用 System.out.println(num); } }
重点:异常的处理机制2:throws
package 异常; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; /* * 异常处理方式2:throws+异常类型 * 1、"throws+异常类型"写在方法的声明处,指明此方法在执行时,可能会抛出的异常类型 * 一旦当方法体执行时出现异常,仍然会异常代码处生成一个异常类对象,此对象满足throws后面的异常类型时就会被抛出 *异常代码后续代码,就不再执行了 * * 2、体会:try-catch-finally:真正将异常处理掉了 * throws的方式只是将异常抛给了方法的调用者,并没有将异常真正处理掉 * 3、开发中如何选择使用try-catch-finally还是使用throws * 3.1、如果父类中被重写的方法没有用throws方式处理异常,则子类重写的方法也不能使用 * throws处理异常,意味着子类重写的方法中有异常,必须使用try-catch-finally方法去处理 * 3.2、执行的方法a中,先后又调用了另外的几个方法,这几个方法是递进这关系执行的我们建议这几个方法使用throws * 的方式进行处理而执行的方法a可以考虑使用try-catch-finally方式进行处理 * 注:如果一直往throws向上抛,到main()方法的时候就不要再抛了,try-catch-finally一下就行了 */ public class ExcptionTest2 { public static void main(String[] args) { try { medhod1(); } catch (IOException e) { e.printStackTrace(); } } public static void medthod3() { try { medhod1(); } catch (FileNotFoundException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } } public static void medhod1() throws IOException{ medhod(); } public static void medhod() throws FileNotFoundException ,IOException{ File file=null; FileInputStream lw=null; file=new File("hee.txt"); lw=new FileInputSt ream(file); int ar=lw.read(); while(ar!=-1) { System.out.println((char)ar); ar=lw.read(); } lw.close(); } }
finally的使用
package 异常; /* * try-catch-finally中finally的使用 * 1、finally是可选的 * 2、finally中声明的是一定会被执行的代码。即使catch中又出现异常了,或try中有return语句 * catch中有return语句等情况。也会先执行finally的语句,而不是return * * 3、像数据库连接、输入输出流、网络编程Socket等资源,JVM是不能自动回收的,我们需要自己手动的进行资源的释放 * 此时的资源释放,就需要声明在finally中,因为这些操作是不能被其他代码和操作干扰的,是一定要进行释放的 * * * * */ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import org.junit.Test; public class FinallyTest { @Test public void test2() { File file=null; FileInputStream lw=null; try { file=new File("hee.txt"); lw=new FileInputStream(file); int ar=lw.read(); while(ar!=-1) { System.out.println((char)ar); ar=lw.read(); } // lw.close(); 释放资源的操作不能放在这 } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { if (lw!=null) { lw.close(); } } catch (IOException e2) {// TODO: handle exception e2.printStackTrace(); } } } @Test public void testmedaq() { int aa=medaq(); System.out.println(aa); } public int medaq() { try { int []num=new int[10]; System.out.println(num[10]); return 1; } catch (ArrayIndexOutOfBoundsException e) { // TODO: handle exception e.printStackTrace(); return 2; }finally { System.out.println("一定会执行"); } } @Test public void test1() { try { int a=10; int b=0; System.out.println(a/b); } catch (ArithmeticException e) { int []arr=new int [10];//这里出现了异常,表示如果在catch中出现异常时,如果下面不是使用finally语句,而是直接写代码,那就会直接终止,但如果使用了finally语句,那finally中的语句会执行完才终止 System.out.println(arr[10]); }catch (Exception e) { e.printStackTrace(); } // System.out.println("wq ");//如果在catch中有异常那这个代码及后面的代码都不会运行 finally {//如果在catch中有异常那finally中的代码会运行完才报异常 System.out.println("你好"); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?