绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
Java异常架构与异常关键字
2019-10-08 10:21:04

Java 异常简介

Java 异常是 Java 提供的一种识别及响应错误的一致性机制。

Java 异常机制可以使程序中异常处理代码和正常业务代码分离,保证程序代码更加优雅,并提高程序健壮性。在有效使用异常的情况下,异常能清晰的回答 what, where, why 这 3 个问题:异常类型回答了“什么”被抛出,异常堆栈跟踪回答了“在哪”抛出,异常信息回答了“为什么”会抛出。

Java 异常关键字

• try – 用于监听。将要被监听的代码 ( 可能抛出异常的代码 ) 放在 try 语句块之内,当 try 语句块内发生异常时,异常就被抛出。

• catch – 用于捕获异常。 catch 用来捕获 try 语句块中发生的异常。

• finally – finally 语句块总是会被执行。它主要用于回收在 try 块里打开的物力资源 ( 如数据库连接、网络连接和磁盘文件 ) 。只有 finally 块,执行完成之后,才会回来执行 try 或者 catch 块中的 return 或者 throw 语句,如果 finally 中使用了 return 或者throw 等终止方法的语句,则就不会跳回执行,直接停止。

• throw – 用于抛出异常。

• throws – 用在方法签名中,用于声明该方法可能抛出的异常。

下面通过几个示例对这几个关键字进行简单了解。

示例一: 了解 try 和 catch 基本用法

public class Demo1 {

    public static void main(String[] args) {

        try {

            int i = 10/0;

            System.out.println("i="+i);

        } catch (ArithmeticException e) {

              System.out.println("Caught Exception");

            System.out.println("e.getMessage(): " + e.getMessage());

            System.out.println("e.toString(): " + e.toString());

            System.out.println("e.printStackTrace():");

            e.printStackTrace();

        }

    }

}

运行结果:

Caught Exception

e.getMessage(): / by zero

e.toString(): java.lang.ArithmeticException: / by zero

e.printStackTrace():

java.lang.ArithmeticException: / by zero

    at Demo1.main(Demo1.java:6)

结果说明:在try 语句块中有除数为 0 的操作,该操作会抛出 java.lang.ArithmeticException 异常。通过 catch ,对该异常进行捕获。

观察结果我们发现,并没有执行System.out.println( “ i= ” +i) 。这说明 try 语句块发生异常之后, try 语句块中的剩余内容就不会再被执行了。

示例二: 了解 finally 的基本用法

在" 示例一 " 的基础上,我们添加 finally 语句。

public class Demo2 {

    public static void main(String[] args) {

        try {

            int i = 10/0;

              System.out.println("i="+i);

        } catch (ArithmeticException e) {

              System.out.println("Caught Exception");

            System.out.println("e.getMessage(): " + e.getMessage());

            System.out.println("e.toString(): " + e.toString());

            System.out.println("e.printStackTrace():");

            e.printStackTrace();

        } finally {

            System.out.println("run finally");

        }

    }

}

运行结果:

Caught Exception

e.getMessage(): / by zero

e.toString(): java.lang.ArithmeticException: / by zero

e.printStackTrace():

java.lang.ArithmeticException: / by zero

    at Demo2.main(Demo2.java:6)

run finally

结果说明:终执行了finally 语句块。

示例三: 了解 throws 和 throw 的基本用法

throws 是用于在方法声明抛出的异常,而 throw 是用于抛出异常。

class MyException extends Exception {

    public MyException() {}

    public MyException(String msg) {

        super(msg);

    }

}

public class Demo3 {

    public static void main(String[] args) {

        try {

            test();

        } catch (MyException e) {

            System.out.println("Catch My Exception");

            e.printStackTrace();

        }

    }

    public static void test() throws MyException{

        try {

            int i = 10/0;

              System.out.println("i="+i);

        } catch (ArithmeticException e) {

            throw new MyException("This is MyException");

        }

    }

}

运行结果:

Catch My Exception

MyException: This is MyException

    at Demo3.test(Demo3.java:24)

    at Demo3.main(Demo3.java:13)

结果说明:

MyException 是继承于 Exception 的子类。 test() 的 try 语句块中产生 ArithmeticException 异常 ( 除数为 0) ,并在 catch中捕获该异常,接着抛出 MyException 异常。 main() 方法对 test() 中抛出的 MyException 进行捕获处理。

Java 异常架构

1. Throwable

Throwable 是 Java 语言中所有错误与异常的超类。

Throwable 包含两个子类 : Error (错误)和 Exception (异常)它们通常用于指示发生了异常情况。

Throwable 包含了其线程创建时线程执行堆栈的快照,它提供了 printStackTrace() 等接口用于获取堆栈跟踪数据等信息。

2. Error (错误)

定义:Error 类及其子类。程序中无法处理的错误,表示运行应用程序中出现了严重的错误。

特点:此类错误一般表示代码运行时 JVM 出现问题。通常有 Virtual MachineError (虚拟机运行错误)、 NoClassDefFoundError(类定义错误)等。比如 OutOfMemoryError :内存不足错误; StackOverflowError :栈溢出错误。此类错误发生时, JVM 将终止线程。

这些错误是不受检异常,非代码性错误。因此,当此类错误发生时,应用程序不应该去处理此类错误。按照Java 惯例,我们是不应该是实现任何新的 Error 子类的!

3. Exception (异常)

程序本身可以捕获并且可以处理的异常。Exception 这种异常又分为两类:运行时异常和编译时异常。

3.1 运行时异常

定义:RuntimeException 类极其子类,表示 JVM 在运行期间可能出现的错误。

特点:Java 编译器不会检查它。也就是说,当程序中可能出现这类异常时,倘若既 " 没有通过 throws 声明抛出它 " ,也 " 没有用 try-catch 语句捕获它 " ,还是会编译通过。比如 NullPointerException 空指针异常、 ArrayIndexOutBoundException 数组下标越界异常、 ClassCastException 类型转换异常、 ArithmeticExecption 算术异常。此类异常属于不受检异常,一般是由程序逻辑错误引起的,在程序中可以选择捕获处理,也可以不处理。虽然 Java 编译器不会检查运行时异常,但是我们也可以通过 throws 进行声明抛出,也可以通过 try-catch 对它进行捕获处理。如果产生运行时异常,则需要通过修改代码来进行避免。例如,若会发生除数为零的情况,则需要通过代码避免该情况的发生!

RuntimeException 异常会由 Java 虚拟机自动抛出并自动捕获(就算我们没写异常捕获语句运行时也会抛出错误!!),此类异常的出现绝大数情况是代码本身有问题应该从逻辑上去解决并改进代码。

3.2 编译时异常

定义: Exception 中除 RuntimeException 极其子类之外的异常。

特点: Java 编译器会检查它。如果程序中出现外汇返佣http://www.fx61.com/ 此类异常,比如 ClassNotFoundException (没有找到指定的类异常), IOException ( IO 流异常),要么通过 throws 进行声明抛出,要么通过 try-catch 进行捕获处理,否则不能通过编译。在程序中,通常不会自定义该类异常,而是直接使用系统提供的异常类。该异常我们必须手动在代码里添加捕获语句来处理该异常。

4. 受检异常与非受检异常

Java 的所有异常可以分为受检异常( checked exception )和非受检异常( unchecked exception )。

4.1 受检异常

编译器要求必须处理的异常。正确的程序在运行过程中,经常容易出现的、符合预期的异常情况。一旦发生此类异常,就必须采用某种方式进行处理。除 RuntimeException 及其子类外,其他的 Exception 异常都属于受检异常。编译器会检查此类异常,也就是说当编译器检查到应用中的某处可能会此类异常时,将会提示你处理本异常——要么使用 try-catch 捕获,要么使用方法签名中用 throws 关键字抛出,否则编译不通过。

4.2 非受检异常

编译器不会进行检查并且不要求必须处理的异常,也就说当程序中出现此类异常时,即使我们没有try-catch 捕获它,也没有使用throws 抛出该异常,编译也会正常通过。该类异常包括运行时异常( RuntimeException 极其子类)和错误( Error )。

Throwable : Java 中所有的异常都有共同的父类 Throwable (可抛出)。它有两个重要的子类 Error (错误)和 Exception (异常),这两个子类也包含大量的子类。

Error (错误):是程序代码无法处理的错误。大多数是 java 运行时系统的内部错误和资源耗尽错误。应用程序不会抛出该类对象。如果出现了这样的错误,除了告知用户,剩下的就是尽力使程序安全的终止。

Exception (异常):是程序代码本身可以处理的异常,对异常处理以后代码不会终止运行。

* 运行异常:都是 RuntimeException 类及其子类,如 NullPointerException (空指针异常), IndexOutOfBoundsException(数组下标越界异常)

 该异常特点是 Java 并不会检查这类异常,就算没有捕捉处理( try catch )或者抛出异常( throws ),编译依旧会通过。

* 非运行时异常(编译异常):是 RuntimeException 以外的异常,类型上都属于 Exception 类及其子类。这是必须要处理的异常,如果不处理无法通过编译,比如一些强制异常,线程中的异常处理、 IO 流中的异常处理。

异常处理的关键字:

*    try :里面是可能出现异常的语句或者代码块。后面可以跟一个或多个 catch 代码段。出现异常,终止 try 代码段的执行,根据错误的类型找到对应的 catch 执行。

1) 必须在 try 之后添加 catch 或 finally 块。 try 块后可同时接 catch 和 finally 块,但至少有一个块。

2) 必须遵循块顺序:若代码同时使用 catch 和 finally 块,则必须将 catch 块放在 try 块之后。

3) catch 块与相应的异常类的类型相关。

*    catch :出现异常该怎么办 (拿到异常一定做出至少一种处理)

 try {

Thread.sleep(1000);

} catch (Exception ef) {

system.out.println(" 这里好至少有一种处理方法 ");

}

*    finally :无论是否产生异常都会执行。一般用于资源的清除工作,比如 io 流的关闭, jdbc 的驱动关闭。

   InputStream in = null;

try {

in = new FileInputStream(" 文件路径 ");

 

byte[] bt = new byte[in.available()];

 

String str = new String(bt);

System.out.print(str);

} catch (FileNotFoundException e) {

e.printStackTrace();

}

catch (IOException e) {

e.printStackTrace();

}finally {

try {

// 关闭流 , 释放资源

in.close();

} catch (IOException e) {

e.printStackTrace();

}

}

*    throws :用于方法声明时出抛出  

*    throw :用于实际手动抛出

 如果程序代码 try catch 处理不了某种异常(比如异常并不是该代码块产生,只有抛出)、不知道如何处理该异常、不想 try catch ,都可以使用抛出。但是,只要程序不停的调用这个方法,就要不停的抛出。

public static void main(String[] args) throws Exception {

new Test2().demo();

}

public void demo() throws Exception{

int x = 1;

if(x == 1)

throw new Exception(" 手动抛出异常 ");

}

自定义异常类:

1. 通过继承 Exception 类声明自己的异常类

2. 在方法适当的位置,生成自定义异常的实例,并用 throw 抛出

3. 在方法声明部分用 throws 语句声明该方法可能抛出异常

public class MyException extends Exception{

public MyException() {

System.out.println(" 我的异常类 ");

}

}

---------------------------------------------------

public class MyException2 {

static int a;

public static void main(String[] args) throws MyException {

a = 4;

new MyException2().test();

}

public void test() throws MyException{

if(a<10)

throw new MyException();

}

}

 

分享好友

分享这个小栈给你的朋友们,一起进步吧。

应用开发
创建时间:2020-06-17 15:31:04
应用软件开发是指使用程序语言C#、java、 c++、vb等语言编写,主要是用于商业、生活应用的软件的开发。
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

技术专家

查看更多
  • 栈栈
    专家
戳我,来吐槽~