java里的异常处理(Exception)
Exception 是在程序执行过程中发生的一些不希望发生的事情,这些事情如果不被好好处理,就会导致奇怪的结果或者是程序终结。Exception Handler是那些当异常发生时处理这些异常的代码。所以这里只讲三个事儿:

1. 什么是异常(Exception)
1.1 Exceptions in java
1.2 checked 和 unchecked的异常
1.3 error和unchecked exception的不同
2. 如何处理异常 (how to handle exception)
2.1 try-catch-finally
2. 2. throws exception
3.如何创建一个custom的exception类
3.1 如何创建一个custom的exception类
3.2 如何扔throw一个custom的exception
1. 什么是异常(Exception)
Exception 是在程序执行过程中发生的一些不希望发生的事情,这些事情如果不被好好处理,就会导致奇怪的结果或者是程序终结。Exception Hander是那些当异常发生时处理这些异常的代码。java和javascript都用try/catch来处理异常。

1.1 Exceptions in java
exception在java里也是个object。
来个图先

图片来源: http://voyager.deanza.edu/~hso/cis35a/lecture/java13/intro/hier.html
它爸爸是Throwable(面试会考,敲黑板)。它还有个兄弟叫Error。

error and exception的不同:
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch.

The class Exception and its subclasses are a form of Throwable that indicates conditions that a reasonable application might want to catch.

1.2 checked 和 unchecked的异常
Checked exception 是编译的时候就要求被handle的。编译的时候会检测Checked exception如果发生了有没有被handler(有没有加handler)所以也被称为compile-time exception。如果一个class是 Exception的孩子但不是 RuntimeException的孩子,那么它就是checked,写代码的时候被要求加handler 。如果用IDE, 会在写代码时要求handle这类异常。
例如: CloneNotSupportedException, IOException, SQLException,
InterruptedException, FileNotFoundException
Unchecked exception 也被称为runtime exception因为它发生在程序执行时。我们可以添加handler去处理这类异常,也可以不加handler不处理这类异常。如果一个class是 RuntimeException的子孙,那它就是一个unchecked exception。
例如: IllegalMonitorStateException,
ConcurrentModificationException, NullPointerException,
IndexOutOfBoundException, NumberFormatException
1.3 error和unchecked exception的不同
虽然都发生在runtime,但是error不被建议去handle。 大部分情况下即使是加了catch也无法修复。而RuntimeException可以去handle。

2. 如何处理异常 (how to handle exception)
有一些方法在声明的时候就声明扔出一个exception。如果这个exception是checked exception,则调用这个方法的时候就必须handle它。
checked exception就像一个炸弹,如果说方法A的某处扔出一个炸弹,或者从别处接到一个炸弹(调用了另一个扔出exception的方法), 有两种解决方案:

自己把它拆了( try-catch-finally)。 这样的话调用方法A的方法不用担心这个炸弹(异常)了
继续丢出去, 谁调用方法A谁来处理(在A的method declaration的时候加上throws.)
如果采用第一种方案,当方法B调用方法A的时候,方法A已经把炸弹拆了,方法B不用担心任何事情。
如果采用第二种方法,方法B调用方法A的时候知道同时要接到一个炸弹,于是它有两种解决方案,拆了,或者继续throws。

2.1 如何拆炸弹 用try-catch-finally
try-catch:
一个常见的数组越界exception。是个unchecked的exception,因为编译时没有要求handle,所以是个常见的新手 runtime异常。(不要求被handle,但是如果想handle也是可以的。)

import java.io.*;
public class ExceptionTest1 {
   public static void main(String args[]) {
      try {
         int a[] = new int[2];
         System.out.println(a[3]); //数组越界访问
      } catch (ArrayIndexOutOfBoundsException e) {
         System.out.println(e);//虽然没有做有意义的事情,但是阻止了程序死在半截。
      }
      System.out.println("run successfully");
   }
}

一个try可以跟着好几个catch, 为了分开处理不同的错误:

try {
   //doing something
} catch (Exception1 e) {
    // handle the first type exception
    System.out.println("Exception1 happened")
} catch (Exception2 f){
    // handle the first type exception
    System.out.println("Exception2 happened")
}

一个exception发生之后,如果是Exception1类型的,就会被第一个handle,如果不是Exception1类型的就会接着往下找catch,如果是Exception2类型的,就会被第二个catch块handle。
如果Exception1和Exception2是父子关系,则儿子要先被检测,因为如果爸爸先被检测,就永远也到不了儿子那个catch块了。

finally block:
finally block 是无论如何也会发生的一个block。 catch里的代码如果不发生异常就不会被执行,但是finally里面的代码无论如何都会执行。(除非是在try或者catch里面用System.exit(1)结束jvm。)通常用来关闭文件。

try {
         //doing something
      } catch (Exception e) {
          //handle the exception
      }finally {
         //一定会被执行的代码。
      }
   }
}

另外, try-finally也是合法的。

2.2 如何继续甩锅 throws exception
用throws关键词

//m1抛出了一个异常
void m1 throws FileNotFoundException(){
    //大概是想读一些文件,又不想考虑如果文件找不到咋整。(甩锅)
}
//m2调用了m1,相当于从m1手里接到了这个异常,自己不处理,继续往外甩。
void m2 throws FileNotFoundException(){
    m1();//想用m1方法,m1声明如果想用我就要考虑文件找不到的情况。
    //但是m2依然不想考虑文件找不到咋整。
}

来看个综合的例子:
下面代码由于接到了exception没有正确handle而产生编译错误:

import java.io.File;
import java.io.FileReader;
//会有编译错误
public class ReadFileTest {
   public static void main(String args[]) {
      getFile();
   }
   public static void getFile(){
          File file = new File("file.txt");
       FileReader fr = new FileReader(file);//error: unreported exception FileNotFoundException; must be caught or declared to be thrown
   }
}

因为FileReader的constructor throws了一个异常

public FileReader(String fileName) throws FileNotFoundException
1
所以当getFile方法调用FileReader的时候必须handle这个异常。

下面是一个例子用上面两种方法处理异常:

import java.io.File;
import java.io.FileReader;
import java.io.FileNotFoundException;
public class ReadFileTest {
   public static void main(String args[]) {
           getFile1();
           System.out.println("=============");
        try{
           // 因为getFile2又把exception甩出来了,所以main方法得处理它。
           getFile2();
        }catch(FileNotFoundException e){
           System.out.println("Exception handled in main");
        }
      
   }
   //getFile1选择了自己处理,不麻烦调用它的方法
   public static void getFile1() {
        try{
                  File file = new File("file.txt");
               FileReader fr = new FileReader(file);
           }catch(FileNotFoundException e){
               System.out.println("Exception handled in getfile1");
       }
   }
   //getFile2选择了不处理,继续throws
   public static void getFile2() throws FileNotFoundException{
          File file = new File("file.txt");
       FileReader fr = new FileReader(file);
   }
}

运行结果:

Exception handled in getfile1
=============
Exception handled in main

一般来讲,所有的exception到了main方法这里都应该已经被解决了。如果,main方法也不负责任的往外扔。。。

import java.io.File;
import java.io.FileReader;
import java.io.FileNotFoundException;
public class ReadFileTest {
   public static void main(String args[]) throws FileNotFoundException{
           getFile1();
           System.out.println("=============");
        getFile2();
      
   }
   public static void getFile1() {
        try{
                  File file = new File("file.txt");
               FileReader fr = new FileReader(file);
           }catch(FileNotFoundException e){
               System.out.println("Exception handled in getfile1");
       }
   }
   public static void getFile2() throws FileNotFoundException{
          File file = new File("file.txt");
       FileReader fr = new FileReader(file);
   }
}

这样做是可以的。。。在没有文件的情况下(触发exception)运行结果:

Exception handled in getfile1
=============
Exception in thread "main" java.io.FileNotFoundException: file.txt (No such file or directory)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileReader.<init>(FileReader.java:72)
    at ReadFileTest.getFile2(ReadFileTest.java:21)
    at ReadFileTest.main(ReadFileTest.java:8)

3.如何应用custom的exception
3.1 如何创建一个custom的exception类
extends exception和它的孩子们呀

1. class New1Exception extends Exception { } // 创建一个checked exception
2. class NewException extends IOExcpetion { } // 创建一个跟IO相关的exception
3. class NewException extends RuntimeException { } // 创建一 UnChecked exception

来个例子(就是这么简单):

import java.io.*;
class MyException extends Exception
{
    public MyException(String s)
    {
        super("a MyException happens: " + s);
        //还可以做一些其他的事
    }
}

3.2 如何甩出(throw)一个custom的exception
throw 和throws
throw是在方法或者代码块里面,用来扔炸弹 抛出异常。
throws是在方法声明的时候,说明这个方法抛出了异常。

用刚才的MyException写个例子:

import java.io.*;
public class Main
{
    public static void main(String args[])
    {
        try {
            throwTest();
        } catch (MyException e) {
            System.out.println("Caught something");
            System.out.println(e.getMessage());
        }
        //throwTest2是一个正常的方法,扔的exception被自己handle了。
        throwTest2();
        //另用一个block测试test3,
        //如果写在同一个block,throwTest()抛出异常后,throwTest3()不会被执行
        try {
            throwTest3();
        } catch (MyException e) {
            System.out.println("Caught something");
            System.out.println(e.getMessage());
        }
    }
    // 自己不handle,扔出来之后继续在方法声明里告诉调用自己的方法需要handle
    public static void throwTest() throws MyException {
        throw new MyException("something");
    }
    //自己handle了,变成一个正常的方法
    public static void throwTest2() {
        try {
            throw new MyException("somethingElse");
        } catch (MyException e) {
            System.out.println("Caught somethingElse");
            System.out.println(e.getMessage());
        }
    }
    //自己handle了,在catch里继续往外扔。
    public static void throwTest3() throws MyException{
        try {
            throw new MyException("somethingElse2");
        } catch (MyException e) {
           //一个非常不负责任的catch,但是是合法的。
           throw e;
        }
    }
}

输出:

Caught something
a MyException happens: something
Caught somethingElse
a MyException happens: somethingElse
Caught something
a MyException happens: somethingElse2

异常处理(Exception Handling)的更多相关文章

  1. Akka(26): Stream:异常处理-Exception handling

    akka-stream是基于Actor模式的,所以也继承了Actor模式的“坚韧性(resilient)”特点,在任何异常情况下都有某种整体统一的异常处理策略和具体实施方式.在akka-stream的 ...

  2. Exception Handling Considered Harmful

    异常处理被认为存在缺陷 Do, or do not. There is no try. - Yoda, The Empire Strikes Back (George Lucas) by Jason ...

  3. 异常处理与MiniDump详解(3) SEH(Structured Exception Handling)

    write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie 讨论新闻组及文件 一.   综述 SEH--Structured Exception Handlin ...

  4. Exception handling 异常处理的本质

    异常处理的本质:状态回滚或者状态维护. https://en.wikipedia.org/wiki/Exception_handling In general, an exception breaks ...

  5. C#编程.异常处理(Exception Handling Statements)

    C#语言包含结构化异常处理(Structured Exception Handling,SEH). throw The throw statement is used to signal the oc ...

  6. Exception Handling in ASP.NET Web API webapi异常处理

    原文:http://www.asp.net/web-api/overview/error-handling/exception-handling This article describes erro ...

  7. C# to IL 10 Exception Handling(异常处理)

    Exception handling in IL is a big let down. We expected a significant amount of complexity,but were ...

  8. Exception Handling引入MVP

    异常处理(Exception Handling)是所有系统的最基本的基础操作之一,其它的比如日志(Logging).审核(Auditing).缓存(Caching).事务处理(Transaction) ...

  9. Unity、Exception Handling引入MVP

    什么是MVP?在“MVP初探”里就有讲过了,就是一种UI的架构模式. 简单的描述一下Unity和Exception Handling Application Block: Unity是一个轻量级的可扩 ...

  10. 黄聪:Microsoft Enterprise Library 5.0 系列教程(七) Exception Handling Application Block

    原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(七) Exception Handling Application Block 使用企业库异常处理应用程序模块的 ...

随机推荐

  1. C#面向对象22 委托事件反射

    1.委托的定义:声明委托类型(返回值和参数,命名空间中):定义委托对象 (把委托想象成函数中的占位符~因为你并不确定调用哪个函数~) using System; using System.Collec ...

  2. Android中如何判断内存卡是否存在

    if (Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) { /* 得到SD卡得路 ...

  3. Pr PS 笔记

    1. 保存窗口配置    窗口-新建工作区 2. 添加快捷键  编辑-自定义快捷键 3. 添加关键帧,需要下拉轨道 4. 关闭PR声音 5. 视频稳定器 选中素材,右键选择嵌套,嵌套后在子序列把视频画 ...

  4. js定时器 离开当前页面任然执行的问题

    今天在博客上看到有人问 js定时器-----离开当前页面原本匀速运动的div加速了,回到页面若干时间恢复匀速??? 他是js定时器控制一个盒子做旋转动画 离开页面后js还在执行 但是盒子这个dom却被 ...

  5. 解决GitHub下载资源慢的问题

    打开 C:\Windows\System32\drivers\etc\hosts 添加 # GitHub 解决下载速度慢的问题 192.30.253.113 github.com 151.101.18 ...

  6. REST easy with kbmMW #1

    kbmMW 5.0支持REST服务器的开发,并且非常简单,下面看看如何实作一个REST服务器. 首先我们制作一个服务器应用程序,增加一个简单的Form,并放置kbmMW组件. 在Delphi中单击Fi ...

  7. kubernetes之NFS动态提供Kubernetes后端存储卷

    StorageClass作为对存储资源的抽象定义, 对用户设置的NFS申请屏蔽后端存储的细节, 一方面减少了用户对于存储资源细节的关注, 另一方面减轻了管理员手工管理pv的工作, 由系统自动完成pv的 ...

  8. “美登杯”上海市高校大学生程序设计 C. 小花梨判连通 (并查集+map)

    Problem C C . 小 花梨 判连通 时间限制:2000ms 空间限制:512MB Description 小花梨给出

  9. zencart更改css按钮的宽度css buttons

    includes\functions\html_output.php 大概323行的zenCssButton函数 function zenCssButton($image = '', $text, $ ...

  10. unittest 报告——HTMLTestRunner/BSTestRunner+代码覆盖率

    1. HTMLTestRunner.py 代码(python3)如下: python2:  https://github.com/tungwaiyip/HTMLTestRunner "&qu ...