【Java】异常(Exception)

网友投稿 277 2022-08-25

【Java】异常(Exception)

文章目录

​​Java中的异常(Exception)​​

​​一、异常的基本概念​​​​二、异常的主要分类​​

​​2.1 异常的分类​​​​2.2 常见的异常​​

​​三、异常的捕获和处理​​

​​3.2.1 抛出异常---throw(自定义异常)​​​​3.2.2 对比 throws 和 throw​​

​​3.3 方式二:捕捉(try...catch...final...)​​

​​四、getMessage() 与 printStackTrace()​​​​五、finally语句​​

​​5.1 深入 finally 语句块​​

​​六、final、finalize、finally区别​​​​七、方法覆盖与异常​​

Java中的异常(Exception)

一、异常的基本概念

1.什么是异常?

第一,异常模拟的是我们日常生活中"不正常"的事件第二,java中采用"类"去模拟异常第三,异常类是可以创建对象的:NullPointerException e = 0x1234;

e是引用类型,e中保存的内存地址指向堆内存中的"对象"这个对象一定是NullPointerException类型的这个对象表示真实存在的异常事件NullPointerException是一类异常

2.异常机制的作用

JAVA语言为我们提供了一种完善的异常处理机制作用是:程序发生异常事件之后,为我们输出详细的信息,可以通过这些信息对程序进行处理,使程序更加完善

public class ExceptionTest01 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int a = 10; int b = 0; int c = a/b; System.out.println(c); System.out.println("hello world!"); /* 以上程序出现异常: * Exception in thread "main" java.lang.ArithmeticException: / by zero at 异常的基本概念.ExceptionTest01.main(ExceptionTest01.java:28) * JVM向控制台输出信息,其本质: 程序执行过程中发生了算数异常这个事件,JVM创建了一个ArithmeticException类型的对象 并且该对象中包含了详细的异常信息,还将这个对象中的信息输出到了控制台 * 异常未被处理时下面的代码不会继续执行,直接退出 }}结果:Exception in thread "main" java.lang.ArithmeticException: / by zero at 异常的基本概念.ExceptionTest01.main(ExceptionTest01.java:31)

​​​​

二、异常的主要分类

2.1 异常的分类

异常主要分为:​​错误​​、​​一般性异常(受控异常)​​、​​运行期异常(非受控异常)​​

错误:如果应用程序出现了Error,那么将无法恢复,只能重新启动应用程序,最典型的Error异常是 — ​​OutOfMemoryError​​受控异常:出现了这种异常必须显示的处理,不显示处理java程序将无法编译通过非受控异常:此种异常可以不用显示的处理

2.2 常见的异常

​​​​

三、异常的捕获和处理

3.1 处理异常的两种方式

import java.io.FileInputStream;import java.io.FileNotFoundException;public class ExceptionTest03 { /** * @param args * @throws FileNotFoundException */ /* 通过抛出异常解决 */ public static void main(String[] args) throws FileNotFoundException { // TODO Auto-generated method stub //创建文件输入流,读取文件 FileInputStream fis = new FileInputStream("c:/ab.text"); /* 通过try/catch方法解决 try { FileInputStream fis = new FileInputStream("c:/ab.text"); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } */ }}结果:Exception in thread "main" java.io.FileNotFoundException: c:\ab.text (系统找不到指定的文件。) at java.io.FileInputStream.open(Native Method) at java.io.FileInputStream.(FileInputStream.java:106) at java.io.FileInputStream.(FileInputStream.java:66) at 异常的捕获和处理.ExceptionTest03.main(ExceptionTest03.java:24)

​​​​

3.2.1 抛出异常—throw(自定义异常)

//顾客相关业务public class CustomerService { // 注册方法 public void register(String name) throws IllegalNameExceptoin { // 完成注册 if(name.length()<6){ //异常 IllegalNameExceptoin i = new IllegalNameExceptoin("用户名长度不小于六位数"); //手动抛异常 throw new IllegalNameExceptoin("用户名长度不小于六位数"); } System.out.println("注册成功!"); }}/* * 自定义无效名字异常 * 1.编译时异常 * 2.运行时异常 */ public class IllegalNameExceptoin extends Exception { //编译时异常 //public class IllegalNameExceptoin extends RunTimeException { 运行时异常 //定义异常一般提供两个构造方法 public IllegalNameExceptoin() { super(); // TODO Auto-generated constructor stub } public IllegalNameExceptoin(String msg) { super(msg); // TODO Auto-generated constructor stub } * * 模拟注册 *public class Test { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub //假如用户提供的用户名 String name = "masd"; //masdasd CustomerService cs = new CustomerService(); try { cs.register(name); } catch (IllegalNameExceptoin e) { // TODO Auto-generated catch block e.printStackTrace(); } }}结果:自定义异常.IllegalNameExceptoin: 用户名长度不小于六位数 at 自定义异常.CustomerService.register(CustomerService.java:14) at 自定义异常.Test.main(Test.java:17)//注册成功!

​​​​

3.2.2 对比 throws 和 throw

​​​​

3.3 方式二:捕捉(try…catch…final…)

语法结构:

try { // 可能出现异常的代码 } catch (异常类型1 变量) { // 处理异常的代码} catch (异常类型2 变量) { // 处理异常的代码} ...

catch语句块可以有多个try…catch…语句块只能执行一个catch语句try…catch…语句会出现三种情况:

在使用多个catch语句时,catch语句的排列顺序应该是先特殊后一般,也就是子类在父类前面(如果子类在父类后面,子类永远不会到达)

例:

import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException; /* 以下程序无法编译通过: try { FileInputStream fis = new FileInputStream("c:/ab.text"); fis.read(); //这个方法里又抛出了IOException异常 } catch (FileNotFoundException e) { e.printStackTrace(); } catch抓取异常不完全 */ try { FileInputStream fis = new FileInputStream("c:/ab.text"); fis.read(); } catch (IOException e) { //这里已经捕获过异常了 e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } //catch可以写多个,但是必须从上到下,从小到大 //捕捉在使用多个catch语句时,catch语句的排列顺序应该是先特殊后一般,也就是子类在父类前面(如果子类在父类后面,子类永远不会到达) public class ExceptionTest05 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub //try...catch...语句块只能执行一个catch语句 try { //程序到此处发生了FileNotFoundException异常 //JVM自动创建了一个FileNotFoundException类型的对象,并将该对象的内存地址赋值给了catch语句中的变量e FileInputStream fis = new FileInputStream("c:/ab.text"); System.out.println("000000"); fis.read(); } catch (FileNotFoundException e) { System.out.println("读取的文件不存在"); //FileNotFoundException将Object类的toString方法重写了 System.out.println(e); //java.io.FileNotFoundException: c:\ab.text (系统找不到指定的文件。) } catch (IOException e) { System.out.println("其他IO异常"); } System.out.println("ABC"); }}结果:读取的文件不存在java.io.FileNotFoundException: c:\ab.text (系统找不到指定的文件。)

​​​​

四、getMessage() 与 printStackTrace()

​​printStackTrace()方法​​:打印出所有与之相关的异常出处,换句话说就是不仅打印出异常名字还是显示出位置。便于程序的调试。​​getMessage()方法​​:打印出具体异常的名字。不显示具体位置,不方便调试程序。

import java.io.FileInputStream;import java.io.FileNotFoundException;public class ExceptionTest06 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub try { FileInputStream fis = new FileInputStream("c:/ab.text"); //JVM为我们执行了以下代码 //FileNotFoundException e = new FileNotFoundException("c:\ab.text (系统找不到指定的文件。)"); } catch (FileNotFoundException e) { //打印异常堆栈信息 //一般都会使用该方式去调试程序 e.printStackTrace(); /* java.io.FileNotFoundException: c:\ab.text (系统找不到指定的文件。) at java.io.FileInputStream.open(Native Method) at java.io.FileInputStream.(FileInputStream.java:106) at java.io.FileInputStream.(FileInputStream.java:66) at 异常的捕获和处理.ExceptionTest06.main(ExceptionTest06.java:15) */ String msg = e.getMessage(); System.out.println(msg); //c:\ab.text (系统找不到指定的文件。) } }}结果:java.io.FileNotFoundException: c:\ab.text (系统找不到指定的文件。)c:\ab.text (系统找不到指定的文件。) at java.io.FileInputStream.open(Native Method) at java.io.FileInputStream.(FileInputStream.java:106) at java.io.FileInputStream.(FileInputStream.java:66) at 异常的捕获和处理.ExceptionTest06.main(ExceptionTest06.java:17)

​​​​

五、finally语句

可以直接与try语句块连用

try...finally...

在finally中的代码一定会执行即使在try块、catch块中出现了return语句,final块中的语句也会执行,发生异常时的执行顺序是:try块、catch块 return 语句之前的语句;finally块中的语句;return语句结束。finally块中语句唯一不执行的情况:在异常代码中执行了 System.exit(1),将退出Java虚拟机。

import java.io.FileInputStream;import java.io.FileNotFoundException;public class ExceptionTest07 { /** * @param args * @throws FileNotFoundException */ public static void main(String[] args) throws FileNotFoundException { // TODO Auto-generated method stub try{ System.out.println("ABC"); return; }finally{ System.out.print("test"); } //ABC test try{ FileInputStream fis = new FileInputStream("c:/ab.text"); System.out.println("ABC"); }finally{ System.out.println("test"); } // test // Exception in thread "main" java.io.FileNotFoundException: c:\ab.text (系统找不到指定的文件。) // at java.io.FileInputStream.open(Native Method) // at java.io.FileInputStream.(FileInputStream.java:106) // at java.io.FileInputStream.(FileInputStream.java:66) // at 异常的捕获和处理.ExceptionTest07.main(ExceptionTest07.java:32) try{ System.exit(0); }finally{ System.out.println("test"); } //只要在执行finally语句之前退出了JVM,则finally语句块就不会执行 }}

​​​​

5.1 深入 finally 语句块

finally的执行原理

public class ExceptionTest08 { public static int m1(){ int i = 10; try{ return i; //10 }finally{ i++; System.out.println(i); //11 } } /* 以上代码的原理: int i = 10; try{ int temp = i; 在运行时内部定义了变量temp return temp ; }finally{ i++; System.out.println(i); //11 } */ /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int i = m1(); System.out.println(i); //10

通常在程序中为了保证某资源一定会释放,一般在 finally语句块中释放资源

import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;public class ExceptionTest08 { /** * @param args */ public static void main(String[]) { // TODO Auto-generated method stub FileInputStream fis = null; try { fis = new FileInputStream("c:/ab.text"); } catch (FileNotFoundException e) { e.printStackTrace(); } finally{ //为了保证资源一定会释放 if(fis!=null){ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } }}

​​​​

六、final、finalize、finally区别

final:修饰变量、修饰类 final修饰的类无法被继承 final修饰的方法无法被覆盖 final修饰的变量无法被更改 final修饰的成员变量需要手动赋值 final与static连用的变量称之为常量,且常量名字母全部大写finally:是异常处理机制中的finally语句处理块finalize:Object类里的一个方法,只是一个方法名 垃圾回收器在回收垃圾数据之前会自动调用

​​​​

七、方法覆盖与异常

重写的方法不能比被重写的方法抛出更宽泛的异常子类不能抛出比父类更多的异常

import java.io.*;public class ExceptionTest10 { /* 1.子类不能抛出比父类更多的异常 class a{ public void m1(){} } class b extends a { public void m1() throws Exception{} } */ class a{ //public void m1() throws FileNotFoundException {} public void m1() throws IOException {} } class b extends a { //public void m1() throws IOException {} public void m1() throws FileNotFoundException {} }}

​​​​

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【Maven】依赖管理
下一篇:让网络直播营销告别“野蛮生长”!(直播互动营销)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~