Java之异常

本文详细介绍了Java中的异常处理机制,包括如何使用throw关键字抛出异常,如Throwable、Exception和NullPointerException等。还讲解了异常说明的作用,如何使用try-catch-finally块来捕获和处理异常,以及如何创建自定义异常。此外,文章提到了异常丢失的情况,如finally块中的return和新的异常抛出会导致原异常信息丢失。

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

Java之异常

异常

在这里插入图片描述

抛出异常

  • 所有标准异常类都有两个构造器:一个是默认构造器,另一个是接收字符串作为参数的构造器。
  • 使用throw关键字来抛出异常对象。
  • 可以抛出任何类型的Throwable对象,它是异常类型的根类。但是通常来说,我们对于不同异常还是抛出对应的异常比较好,可以方便其他人处理。
  •  if (true) {
         throw new Throwable();
     }
    
     if (true) {
         throw new Exception("hello");
     }
    
     if (true) {
         throw new NullPointerException("空指针异常");
     }
    
  • 异常说明:
    • 定义:它属于方法声明的一部分,跟在形式参数列表之后。
    • 作用:在明确会发送异常时,要么对异常进行处理,要么就使用异常说明,告知他人此方法将抛出异常,调用时需进行处理,他也可以选择处理还是继续向上抛出,如果最后被某个人处理了,那么就没问题,否则,程序会报出此异常。
    • 用法:使用throws关键字加上所有潜在异常类型的列表。
    • 可以只写一个异常类型来抛出所有可能的异常,就是Exception。
      •  public void test() throws NullPointerException, IndexOutOfBoundsException {
        
         }
        

捕获异常

try块

  • 作用:可以用来在方法内设置一个特殊的块去捕获异常。
  • 用法:在try关键字后面跟一个代码块,将可能发生异常的代码放入其中。
  •  try {
         //这里编写可能发生异常的代码
     }
    

异常处理

  • 当try块抓到了异常,我们就必须得想办法处理,此时就该异常处理程序上场了。
  • 异常处理程序是跟在try块后面的catch子句。
  • catch子句:
    • 用法:在catch关键字后面跟一个括号,再跟一个代码块,括号中是异常的对象及类型,代码块是编写怎么处理异常。
    • catch子句可以有多个,多个子句分别用来处理try块中代码可能抛出的所有种类的异常。
    • 当异常被抛出时,异常处理机制将查找参数与异常匹配的第一个处理程序,然后进入catch子句中执行。
    • 可以使用Exception对象的printStackTrace()方法打印从方法调用到异常抛出的堆栈。
    • 可以只写一个异常处理程序来捕获所有类型的异常,就是Exception,但是,最好把它放在最后,以防止前面有更具体的类型与异常相匹配。
    • 捕获了异常时,也可以不处理,使用throw继续向外抛出。同时,你可以使用fillInStackTrace()方法将异常的发生地更新。
      •  catch (Exception e) {
         	throw e.fillInStackTrace();
         }
        
    • 注:只有抛出的异常和catch声明的异常相匹配才会进入执行。
    •  catch (Exception e) {
           //这里编写处理异常的代码
       }
      

使用finall清理

  • 它是try是否会抓到异常都会执行的块。
  • 它通常与用于关闭资源等。
  • 使用:使用finally加一个代码块。
  • 它要么跟在try块后,要么跟在最后一个catch子句后。
    •  try {
           
       } catch (Exception e) {
           
       } finally {
           
       }
       
       try {
           
       } finally {
           
       }
      
  • finally子句永远会得到执行。
    •  try {
           System.out.println("try 1");
           if (true) {
               return;
           }
           System.out.println("try 2");
       } catch (Exception e) {
      
       } finally {
           System.out.println("finally 1");
       }
       
       输出:
       try 1
       finally 1
      

创建自定义异常

  • 可以从已有的异常类进行继承,尽量选择意思相近的异常类,如果找不到就使用Exception。
  • 所有异常的基类是Exception,Exception又是继承自Throwable类。
  • Throwable:
    • 可以调用以下方法打印堆栈信息。
    •  try {
           throw new Throwable("MyException");
       } catch (Throwable e) {
           System.out.println("getMessage():" + e.getMessage());
           System.out.println("getLocalizedMessage():" + e.getLocalizedMessage());
           System.out.println("toString():" + e);
           System.out.println("printStackTrace():");
           e.printStackTrace(System.out);
       }
       
       输出:
       getMessage()MyException
       getLocalizedMessage()MyException
       toString()java.lang.Throwable: MyException
       printStackTrace()java.lang.Throwable: MyException
       	at com.eos.javalearn.JavaLearnClass.main(JavaLearnClass.java:886)
      
    • 还可以使用getStackTrace()方法获取一个由栈轨迹中的元素所组成的数组,栈顶元素时异常抛出之处,栈底是第一个方法调用。获取之后可以打印每个元素的方法名、行号、所在文件的名字等等。
      •  try {
         	throw new Throwable("MyException");
         } catch (Throwable e) {
         	for (StackTraceElement ele : e.getStackTrace()) {
             	System.out.println(ele.getMethodName());
             	System.out.println(ele.getFileName());
             	System.out.println(ele.getLineNumber());
             	System.out.println("-------------------------------");
         	}
         }
        
  •  class MyException extends Exception {
    
     	public MyException() {
     	}
    
     	public MyException(String message) {
         	super(message);
     	}
     }
     
     public class JavaLearnClass {
    
     	public void test() throws MyException {
         	System.out.println("test()");
         	throw new MyException();
     	}
    
     	public void test1() throws MyException {
         	System.out.println("test1()");
         	throw new MyException("自定义异常");
     	}
    
     	public static void main(String[] args) {
    
         	JavaLearnClass javaLearnClass = new JavaLearnClass();
         	try {
             	javaLearnClass.test();
         	} catch (MyException e) {
             	System.out.println("捕获住了MyException异常!");
             	e.printStackTrace();
         	}
         	try {
             	javaLearnClass.test1();
         	} catch (MyException e) {
             	System.out.println("捕获住了MyException异常!");
             	e.printStackTrace();
         	}
         }
     }
     
     输出:
     test()
     捕获住了MyException异常!
     test1()
     捕获住了MyException异常!
      
     com.eos.javalearn.MyException
     	at com.eos.javalearn.JavaLearnClass.test(JavaLearnClass.java:857)
     	at com.eos.javalearn.JavaLearnClass.main(JavaLearnClass.java:869)
     com.eos.javalearn.MyException: 自定义异常
     	at com.eos.javalearn.JavaLearnClass.test1(JavaLearnClass.java:862)
     	at com.eos.javalearn.JavaLearnClass.main(JavaLearnClass.java:875)
    

异常丢失

  • ①在finally中使用return,导致异常丢失;
    • 如下:finally里进行了return,如果没有这个return,throw抛出的异常将会被打印出来,但是加了return之后则不会打印。
    •  try {
           System.out.println("try 1");
           if (true) {
               throw new RuntimeException();
           }
           System.out.println("try 2");
       } finally {
           System.out.println("finally 1");
           return;
       }
       
       输出:
       try 1
       finally 1
      
  • ②异常被抑制:
    • 如下:在finally中抛出了另一个异常,如果不抛出该异常时,try中的异常会正常打印,但是加上了之后则只会打印新的异常,try的异常将丢失。
    •  try {
           System.out.println("try 1");
           if (true) {
               throw new RuntimeException();
           }
           System.out.println("try 2");
       } finally {
           System.out.println("finally 1");
           throw new NullPointerException();
       }
       
       输出:
       try 1
       finally 1
       java.lang.NullPointerException
       	at com.eos.javalearn.JavaLearnClass.main(JavaLearnClass.java:906)
      
  • ③只捕获异常但不处理:
    • 如下:你进行了异常捕获,但是catch中没有任何处理或者打印异常的堆栈,导致异常发生时看不到任何信息。等于说是你把这个异常给私吞了,在你或他人遇到遇到问题时,只能看见异常现象,但是想通过log查看异常信息时却没有任何打印,这是要极力避免的。
      •  try {
         	throw new RuntimeException();
         } catch (Exception e) {
         
         }
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值