0
点赞
收藏
分享

微信扫一扫

Java - 异常

程序员知识圈 2022-01-13 阅读 30

文章目录

1 异常

  • 异常是程序在编译或运行时可能出现的问题
  • 用户输入的数据格式不正确等…
  • 数组越界、空指针异常、等…

1.1 异常分类

  • 异常层次结构
    在这里插入图片描述
  • Error
    • 系统级别问题、JVM退出等,代码无法控制
  • 运行时异常又叫非检查型异常 (RuntimeException及其子类)
    • RuntimeException异常,一定是你的代码有问题
    • 举例:
         package exception;
         public class Demo01 {
         public static void main(String[] args) {
      
             //数字转换异常:NumberFormatException
             System.out.println(Integer.valueOf("aa"));
             
             //数学操作异常:ArithmeticException
             System.out.println(1/0);//ArithmeticException
             
             //类型转换异常:ClassCastException
             Object o = 10;
             String c = (String)o;
             System.out.println(c);
      
             //数组索引越界异常:ArrayIndexOutOfBoundsException
             int[] a = {1,2,3,2,1};
             System.out.println(a[5]); 
             
             //空指针异常:NullPointerException
             String b = null;
             System.out.println(b.startsWith("a"));
         }
      }
      
  • 编译时异常又叫检查型异常 (除RuntimeException之外所有的异常)
    • 举例:
      • 试图超越文件末尾继续读取数据
      • 试图打开一个不存在的文件

2 处理异常

  • 有两种方式:
    • 抛出异常:throws 不对异常进行处理,如果异常最终抛给虚拟机将导致程序死亡
    • 捕获异常:try-catch 捕获异常可以在发生异常时处理异常,避免程序终止

2.1 抛出异常

2.1.1 抛出异常步骤

  • 1、首先明白要抛出什么类型的异常类 (EOFException)
  • 2、然后创建这个异常类对象 (new EOFException()😉
  • 3、 将对象抛出 (throw new EOFExcepton()😉
package core_Exception;
import java.io.EOFException;
public class Demo01 {
    ...
    public void m() throws EOFException {
        ...
        if(...){
            throw new EOFException();
        }
        ...
    }
}
  • throws: 用在方法上,可以将方法内部出现的异常抛出去给本方法的调用者。

2.1.2 抛出自定义异常类

  • Java自带的异常类都不能很清楚描述问题,需要自己创建异常类
  • 自定义异常类的步骤
    • 1、定义一个异常类继承Exception或它的子类
    • 2、包含两个构造器 (无参构造器和包含父类构造器的有参构造器)
    • 3、在可能出现异常的地方 throw new 自定义对象
  • 举例:自定义了一个异常类 IlleagalNumberException
    package exception;
    public class IlleagalNumberException extends Exception{
    
        public IlleagalNumberException() { }
        
        public IlleagalNumberException(String message) {
            super(message);
        }
    }
    

2.2 捕获异常

2.2.1 try-catch

  • 捕获异常语句:
	try{
		...
	}catch(某种异常类 e){
		e.printStackTrace();
	}catch(另一种异常类 e){
		e.printStackTrace();
	}
  • 如果try语句块中的代码发生异常,抛出的异常和catch中的某个匹配。
    • 程序将跳过try语句块的剩余代码
    • 执行对应catch块中的代码
  • 如果try语句块没有异常,则跳过catch
  • 如果try抛出的异常在catch中都没有,则方法立即退出,程序终止
  • 举例:
package exception;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Demo03 {
    public static void main(String[] args) {
        m("2021-01-01 12:21:00");
    }
    public static void m(String date) {
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date parse = simpleDateFormat.parse(date);
            System.out.println(parse);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}
/*
官方建议
try{
	...
}catch(Exception e){
	e.printStackTrace();
}
*/

2.2.2 catch中再次抛出异常

package core_Exception;

public class Demo02 {
    public static void main(String[] args) throws IlleagalException {
		//方式一
        try {
            System.out.println("");
        } catch (ArrayIndexOutOfBoundsException e) {
            throw new IlleagalException("hello" + e.getMessage());
        }
		//方式二 提倡
        try {
            System.out.println("");
        } catch (ArrayIndexOutOfBoundsException e) {
            IlleagalException iE = new IlleagalException("hello");
            iE.initCause(e);
            throw iE;
        }
    }
}

class IlleagalException extends Exception {
    public IlleagalException() {
    }
    public IlleagalException(String message) {
        super(message);
    }
}
  • 提倡方式二的这种包装技术,因为可以使用下面语句获取原始异常
    • Throwable cause = iE.getCause();

2.2.3 finally子句

  • try-catch-finally
   try{
   		...
   }catch(IOException e){
		...
   }finally{
		...
   }
  • 如果try语句块中的资源在抛出异常前就已经获得,如果发生异常,会导致资源没有关闭。
  • finally 就是用来关闭资源的。finally不管try中是否发生异常,finally代码最后都会执行。
    var fis = new FileInputStream(...);
    try{
        ...
    }catch(IOException e){
        e.printStackTrace();
    }finally{
        fis.close();
    }
    
  • 注意:finally 中不要放return continue thro break这些会改变控制流的语句
  • 关闭资源更好的方式: try-with-resources

2.2.4 try-with-rsources语句

//1.7
//try块退出后,会自动运行rs.close(); 关闭资源
try( Resources rs = ...){  
    work with rs;
}

//1.9+
Resources rs = ...;  //资源声明可以在try块外
try(rs){
    work with rs;
}
  • try-with-Resources 也可以有 catch子句、finally子句。这些子句在资源关闭后执行。
try(var in = new Scanner(new FileInputStream("/"), StandardCharsets.UTF_8)){
    while(in.hasNext()){
        System.out.println(in.next());
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
}finally {
    System.out.println("");
}

3 处理异常的技巧

  • throws 用于不知道怎样处理的异常
  • try/catch 用于知道如何处理的异常
  • 异常处理不能代替简单的测试,只在异常情况下使用异常
  • 不过分地细化异常 多个try-catch 可以写成 try-catch-catch
  • 不要压制异常
  • 尽量抛出合适的子类,而不是只是RuntimeException异常
  • 早抛出,晚捕获;不要羞于抛出异常,更高层的方法通常可以更好的通知用户发生了错误。

参考资料

举报

相关推荐

java异常

Java:异常

【JAVA】异常

【Java异常】

Java——异常

Java异常

异常(Java)

0 条评论