Java 异常处理

 

1、java 异常

异常指不期而至的各种状况,如:文件找不到、网络连接失败、非法参数等。

异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程。

Java通过API中 Throwable 类的众多子类描述各种不同的异常。因而,Java异常都是对象,是Throwable子类的实例,描述了出现在一段编码中的 错误条件。当条件生成时,错误将引发异常。

      Java异常类层次结构图:

        

java中将程序出现问题封装成了一个 Throwable
   Throwable 分两种:Error(错误)和Exception(异常)
         Error(错误):严重问题,指运行时环境发生的错误,由jvm自动生成并抛出。例如JVM 内存溢出。

         Exception(异常):不严重的问题,程序可以处理也必须要处理的(重点)

 注意:异常和错误的区别:异常能被程序本身可以处理,错误是无法处理。

异常(Exception)分两种:      

       RuntimeException(运行时期异常): 在运行时期,检查异常.在编译时期,运行异常不会编译器检测(不报错),可处理,可不处理。        

      编译时期异常:除了运行期异常以外,其他全是编译时期异常,在编译时期,就会检查,如果没有处理异常,则编译失败不能运行。

 

2、处理异常机制

异常处理机制为:抛出异常,捕捉异常。

java.lang.Throwable常用方法等:

 2.1 捕获异常:try、catch 和 finally

 try{               
    需要被监测的代码块
}catch(异常的名称 引用名称){ 
    处理方式 
}finally{               
    无论是否捕获或处理异常,finally块里的语句都会被执行。
    当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。永远返回finally中的结果。
    在以下4种特殊情况下,finally块不会被执行:         
        1)在finally语句块中发生了异常。         
        2)在前面的代码中用了System.exit(0)退出程序。         
        3)程序所在的线程死亡。         
        4)关闭CPU。 
 }

    注意:
         1)try和catch都不能单独使用,必须连用。finally不能单独使用.
         2)finally有return语句,永远返回finally中的结果,避免使用该情况。
     执行的流程:当需要被监测的代码块中一旦有异常发生,jvm就将该异常封装成一个异常对象,在传递到相应的catch中进行处理
     注意:

         1)当try中代码块一旦有异常发生就直接执行相应catch中代码,try后面的代码就不会再执行 
         2)catch可以有多个,每个catch块中代码都可以写不同的处理方式
         3)捕获异常的时候可以直接捕获父类异常,但是必须写在最后一个catch中
         4)捕获异常的时候建议捕获更具体的异常,这样处理起来更加具体

		try{
			int n = 10 / 0;
			int[] arr = new int[10];
			arr[10] = 100;
			
		}catch(ArithmeticException e){//e=0x1111
			System.out.println("除数不能为0!");
			System.out.println(e.getMessage());//打印异常出错的信息
//			e.printStackTrace();//打印异常出错的详细信息,异常的名称,异常的信息,异常出错的位置
		}catch(ArrayIndexOutOfBoundsException e){
			System.err.println("索引越界啦!");//红色的字体输出
		}catch(Exception e){
			System.out.println("发生异常了------");
		}finally{
			System.out.println("finally一定会执行,不信试试!");
		}
//结果
除数不能为0!
/ by zero
finally一定会执行,不信试试!

2.2 、抛出异常:throws/throw 关键字

       如果一个方法没有捕获一个检查性异常,那么该方法必须使用 throws 关键字来声明。

抛出异常:

    throw:运用于方法内部,用于给调用者抛出一个异常对象,和return类似,return 是返回是一个值,throw 是返回一个错误给该方法的调用者。

    throws:运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常)。

异常转译:当位于最上层的子系统不需要关心底层的异常细节时,常见的做法是捕获原始的异常,把它转换为一个新的不同类型的异常,再抛出新的异常。

异常链:把原始的异常包装为新的异常类,从而形成多个异常的有序排列,有助于查找异常的根本原因。

注意:

       通过 throws 来处理异常,并没有真正的处理异常,仅仅是让程序通过编译能够运行,想真正的处理异常还是得用 try...catch

public void deposit(double amount) throws IOException,ArithmeticException  {
    // Method implementation
    throw new RemoteException();
  }

定义异常处理时,什么时候定义try,什么时候定义throws呢?

         功能内部如果出现异常,如果内部可以处理,就用try;

         如果功能内部处理不了,就必须声明出来,让调用者处理。

3. 自定义异常

在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。一般继承Exception 类即可。

  • 所有异常都必须是 Throwable 的子类。
  • 如果写一个检查性异常类,则需要继承 Exception 类。
  • 如果写一个运行时异常类,那么需要继承 RuntimeException 类(推荐使用)。
class MyException extends Exception{ }

public class MyException extends RuntimeException { }

在程序中使用自定义异常类,大体可分为以下几个步骤。
(1)创建自定义异常类。
(2)在方法中通过throw关键字抛出异常对象。
(3)如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。
(4)在出现异常方法的调用者中捕获并处理异常。

public class MyException extends RuntimeException {
    public MyException() {
        super();
    }

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

    /**
     *
     * @param message 当前异常的信息/原因
     * @param cause  当前异常的根本原因 e.printStackTrace();
     */
    public MyException(String message, Throwable cause) {
        super(message, cause);
    }
}

=== demo 类===    
    public static void main(String[] args) {
        int res = div(10,0);
        System.out.println(res);
    }
    public static int div(int a, int b) {
        int res;
        try {
            res = a / b ;
        }catch (ArithmeticException  e){
            e.printStackTrace();
            throw new MyException("除数不能为0!", e);
        }
        return res;
    }

    

4、Java7 的异常新特性

1)一个catch子句捕获多个异常

     Java7 改进了catch子句的语法,允许在其中指定多种异常,每个异常类型之间使用“|”来分隔。如:

    public static void main(String[] args) {
        int a = 10;
        int b = Integer.parseInt("hello");
        try {
            int res = a / b;
            System.out.println(res);
        } catch (ArithmeticException | NumberFormatException e){
            e.printStackTrace();
        }catch (Exception e) { 
            e.printStackTrace();
        }
    }

需要注意:

       (1)在catch子句中声明捕获的这些异常类中,不能出现重复的类型,也不允许其中的某个异常是另外一个异常的子类,否则会出现编译错误。

       (2)在catch子句中声明了多个异常类,那么异常参数的具体类型是所有这些异常类型的最小上界。

2)try-with-resources:自动资源关闭

       Java7 以前对某些资源的操作是需要手动关闭,如InputStream,Writes,Sockets,Sql等,需要在finally中进行关闭资源的操作,现在不需要使用finally来保证打开的流被正确关闭,Java7 之后可采用try-with-resources方式后,不需要再次声明流的关闭。        

       使用try-with-resources的资源对象有:任何实现了 java.lang.AutoCloseable接口 java.io.Closeable接口 的对象。为了支持这个行为,所有可关闭的类将被修改为可以实现zhe这两个(可关闭的)接口之一。

          

   如果在try语句中写入了没有实现该接口的类,会提示:

The resource type File does not implement java.lang.AutoCloseable

     

public class Student implements Closeable {
    @Override
    public void close() throws IOException {
    }
}
    // java 7 之前
    public static void main(String[] args) {
        OutputStream out = null;
        try {
            out = new FileOutputStream("E:/123.txt");
            out.write(1);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(out != null){ // 关闭资源
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    // java 7 之后
    public static void main(String[] args) {
        try (
            // 存放在这里的资源类必须实现 java.lang.AutoCloseable接口 或者 java.io.Closeable接口
            OutputStream out = new FileOutputStream("E:/123.txt");
            //Student student = new Student();
         ){
            out.write(1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

 

参考文章: https://blog.csdn.net/hguisu/article/details/6155636

常见的RuntimeException异常

ends ~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值