java进程夯死日志错误关键字,java夯实基础系列:异常

一.概述:

异常你可以认为是对象,在xx情况下产生异常对象,异常对象是虚拟机产生的,不是我们来定义的,java中异常也是对象。

异常:中断了正常指令流的事件

异常和语法错误是完全不一样的东西

异常时运行中出现的,而语法错误连编译都是通不过的

二.异常体系:

类图

0818b9ca8b590ca3270a3433284dd417.png

Throwable():Throwable 类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。类似地,只有此类或其子类之一才可以是 catch 子句中的参数类型。

Error(错误):一般是指java虚拟机相关的问题,如系统崩溃、虚拟机出错误、动态链接失败等,这种错误无法恢复或不可能捕获,将导致应用程序中断,通常应用程序无法处理这些错误,因此应用程序不应该捕获Error对象,也无须在其throws子句中声明该方法抛出任何Error或其子类。

Exception(异常):是中断了正常指令流的事件,是程序本身可以处理的异常。 Exception 类有一个重要的子类RuntimeException。RuntimeException 类及其子类表示“JVM 常用操作”引发的错误。例如,若试图使用空值对象引用、除数为零或数组越界,则分别引发运行时异常(NullPointerException、ArithmeticException)和 ArrayIndexOutOfBoundsException。

注意:异常和错误的区别:异常能被程序本身可以处理,错误是无法处理。程序员对error无能为力,只能处理exception,对异常的处理关系到系统的健壮性。

异常对象包含的常用方法:

1.getMessage();返回该异常的详细描述字符

2.printStackTrace():将该异常的跟踪栈信息输出到标准错误输出。

3.printStackTrace(PrintStream s):将该异常的跟踪栈信息输出到指定的输出流

4.getStackTrace():返回该异常的跟踪栈信息。

java的异常分类

Exception 这种异常分两大类运行时异常和非运行时异常(编译异常)。程序中应当尽可能去处理这些异常。

运行时异常:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。

运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。

非运行时异常 (编译异常):是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

三.java异常处理机制

在 Java 应用程序中,异常处理机制为:抛出异常,捕捉异常。

抛出异常:当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统,异常对象中包含了异常类型和异常出现时的程序状态等异常信息。运行时系统负责寻找处置异常的代码并执行。

捕获异常:在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器(exception handler)。潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合。当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适 的异常处理器。运行时系统从发生异常的方法开始,依次回查调用栈中的方法,直至找到含有合适异常处理器的方法并执行。当运行时系统遍历调用栈而未找到合适 的异常处理器,则运行时系统终止。同时,意味着Java程序的终止。捕获的异常有两种处理方法:

1.在方法中用try…catch语句捕获并处理异常,catach语句可以有多个,用来匹配多个异常。例如:

public void p(int x){

try{

...

}catch(Exception e){

...

}finally{

...

}

}

try-catch语句还可以包括第三部分,就是finally子句。它表示无论是否出现异常,都应当执行的内容。

2.对于处理不了的异常或者要转型的异常,在方法的声明处通过throw语句抛出异常。例如:

public void test1() throws MyException{

...

if(....){

throw new MyException();

}

}

四.方法1:try cach finally

说明:

try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。

catch 块:用于处理try捕获到的异常。

finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。在以下4种特殊情况下,finally块不会被执行:

1)在finally语句块中发生了异常。

2)在前面的代码中用了System.exit()退出程序。

3)程序所在的线程死亡。

4)关闭CPU。

**try-catch-finally 规则(异常处理语句的语法规则)

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

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

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

4) 一个 try 块可能有多个 catch 块。若如此,则执行第一个匹配块。即Java虚拟机会把实际抛出的异常对象依次和各个catch代码块声明的异常类型匹配,如果异常对象为某个异常类型或其子类的实例,就执行这个catch代码块,不会再执行其他的 catch代码块

5) 可嵌套 try-catch-finally 结构。

6) 在 try-catch-finally 结构中,可重新抛出异常。

7) 除了下列情况,总将执行 finally 做为结束:JVM 过早终止(调用 System.exit(int));在 finally 块中抛出一个未处理的异常;计算机断电、失火、或遭遇病毒攻击。

**try、catch、finally语句块的执行顺序

1)当try没有捕获到异常时:try语句块中的语句逐一被执行,程序将跳过catch语句块,执行finally语句块和其后的语句;

2)当try捕获到异常,catch语句块里没有处理此异常的情况:当try语句块里的某条语句出现异常时,而没有处理此异常的catch语句块时,此异常将会抛给JVM处理,finally语句块里的语句还是会被执行,但finally语句块后的语句不会被执行;

3)当try捕获到异常,catch语句块里有处理此异常的情况:在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,程序将跳到catch语句块,并与catch语句块逐一匹配,找到与之对应的处理程序,其他的catch语句块将不会被执行,而try语句块中,出现异常之后的语句也不会被执行,catch语句块执行完后,执行finally语句块里的语句,最后执行finally语句块后的语句;

五.方法2:抛出异常

使用throws抛出异常

使用throws抛出异常的思路是:当前方法不知道如何处理这种类型的异常,该异常应该由上一级调用者处理,如果main方法也不知道应该如何处理这种类型的异常,也可以使用使用throws声明抛出异常,该异常将交给JVM来处理。

JVM对异常的处理方法:打印异常跟踪栈的信息,并终止程序运行,所以有很多程序遇到异常后自动结束。

使用throws抛出异常的格式:

throws声明的抛出的语法格式紧跟在方法之后,可以声明多个异常类,多个异常类之间以逗号隔开。一旦使用了throws语句声明抛出异常,就不用再使用try…catch来捕获异常了。

如:throws ExceptionClass1,ExceptionClass2…

注意点1:如果某段代码调用了一个带throws声明的方法,该方法声明抛出了Checked异常,这表明该方法希望它的调用者来处理该异常。那么这段代码要么放在try块中显示捕获该异常,要么这段代码处于另一个带throws声明抛出的方法中。

//方法一:

import java.io.FileInputStream;

import java.io.IOException;

public class TestException2 {

// test() 方法抛出了异常,那么test()方法的调用者要么放在try块中显示捕获该异常,要么这段代码处于另一个带throws声明抛出的方法中。

// 以下为后者的处理方法

public static void test() throws IOException

{

FileInputStream fis = new FileInputStream("a.txt");

}

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

{

test();

}

}

//方法二:

import java.io.FileInputStream;

import java.io.IOException;

public class TestException2 {

public static void test() throws IOException

{

FileInputStream fis = new FileInputStream("a.txt");

}

public static void main(String[] args)

{

try

{

test();

} catch (IOException e)

{

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

使用throw抛出异常

如果需要在程序中自行抛出异常,应使用throw语句,throw语句可以单独使用,throw语句抛出的不是异常类,而是一个异常实例,而且每次只能抛出一个异常实例。throw语句的格式如下:throw ExceptionInstance;

throw语句抛出异常的两种情况:

1.当throw语句抛出的异常是Checked异常,则该throw语句要么处于try块里显式捕获该异常,要么放在一个带throws声明抛出的方法中,即把异常交给方法的调用者处理。

2.当throw语句抛出的异常是Runtime异常,则该语句无须放在try块内,也无须放在带throws声明抛出的方法中,程序既可以显式使用try…catch来捕获并处理该异常,也可以完全不理会该异常,把该异常交给方法的调用者处理。

public class TestException3 {

public static void throwChecked(int a) throws Exception

{

if (a < 0)

{

/** * 自行抛出Exception异常 改代码必须处于try块里,或处于带throws声明的方法中 */

throw new Exception("a的值大于0,不符合要求");

}

}

public static void throwRuntime(int a)

{

if (a < 0)

{

/** * 自行抛出RuntimeException异常,既可以显式捕获该异常 也可以完全不用理会该异常,把该异常交给方法的调用者处理 */

throw new RuntimeException("a的值大于0,不符合要求");

} else

{

System.out.println("a的值为:" + a);

}

}

public static void main(String[] args)

{

try

{

/** * 此处调用了带throws声明的方法,必须显示捕获该异常(使用try...catch) 否则,要在main方法中再次声明抛出 */

throwChecked(-3);

} catch (Exception e)

{

System.out.println(e.getMessage());

}

throwRuntime(3);

}

}

throw和throws关键字的区别

throw用来抛出一个异常,在方法体内。语法格式为:throw 异常对象。

throws用来声明方法可能会抛出什么异常,在方法名后,语法格式为:throws 异常类型1,异常类型2…异常类型n。

throw用在函数内部,后面跟的是异常类对象,throws用在函数后面,后面跟的是异常类

throw

throw是语句抛出异常。它不可以单独使用,要么与try…catch配套使用,要么与throws配套使用。

格式:throw new 异常名(参数);

假设f方法里某语句抛出了A异常,则f方法有两种方式来处理A异常

①throws A 谁调用f方法,谁处理A异常(用try catch),f方法本身不处理A异常

②try{。。。。}catch{}{。。。}f方法本身自己来处理A异常

throws

throws是方法抛出异常。在方法声明中,如果添加了throws子句,我这个函数不对异常进行处理,而是在调用这个函数的地方对异常进行处理。

作用:把运行时期出现的问题转移到编译时期出现。

使用方法:在函数后使用throws声明抛出异常,那么调用者必须处理

处理方式有两种:

1:使用try{} catch(){}处理

2:使用throws继续声明抛出异常。

六.自定义异常

我们不必拘泥于Java中已有的异常类型

Java定义的异常肯定是一些通用的异常,但是我们做项目,不同的项目的需求和问题是不一样的,问题就是异常,这些异常时java没有给我们定义的,所以我们还需要自己定义自己需要的异常。

Java自定义异常的使用要经历如下四个步骤

1、定义一个类继承Throwable或其子类。

2、添加构造方法(当然也可以不用添加,使用默认构造方法)。

3、在某个方法类抛出该异常。

4、捕捉该异常。

创建Exception或者RuntimeException的子类即可得到一个自定义的异常类。例如:

public class MyException extends Exception{

public MyException(){}

public MyException(String smg){

super(smg);

}

}

使用自定义的异常

用throws声明方法可能抛出自定义的异常,并用throw语句在适当的地方抛出自定义的异常。例如:

在某种条件抛出异常

public void test1() throws MyException{

...

if(....){

throw new MyException();

}

}

七.参考资料:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值