JAVA抛未找到对象异常_Java异常Exception

Java异常

异常是一个事件,发生在程序运行期间,干扰了正常的指令流程,如文件找不到、网络链接找不到、非法参数等。Java中异常都是Throwable子类的实例

Throwable

有两个具体的子类:Exception(异常)和Error(错误),重要子类,并包含大量子类

(1)Error(错误)

程序无法处理的错误

出现此错误表示运行程序中较严重问题,表示代码运行时JVM出现的问题。这些错误是不可查的,在应用程序的控制和处理能力之外,大多数是程序运行时不允许出现的状况。

(2)Exception(异常)

程序本身可处理的异常

Exception 类有一个重要的子类 RuntimeException,RuntimeException 类及其子类表示“JVM 常用操作”引发的错误。例如,若试图使用空值对象引用、除数为零或数组越界,则分别引发运行时异常(NullPointerException、ArithmeticException)和 ArrayIndexOutOfBoundException

93a98a1c4a5a1ef48604a870ab53478f.png

Java异常(Exception、Error)分类

可查的异常(Checked Exceptions)

编译时要求必须处理的异常可查异常一定程度是可预计的,一旦发生这种异常状况,必须采取某种方式处理

除了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常,这种异常的特点是Java编译器会检查它,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则不会通过编译

不可查异常(Unchecked Exceptions)

包括RuntimeException及其子类和错误(Error)

Exception分类

(1) 运行时异常

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

(2) 非运行时异常 (编译异常)

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

处理异常机制

在Java运行中,异常处理机制为:抛出异常,捕获异常

异常总是先被抛出,后被捕捉,并且对于所有的可查异常(允许忽略不可查的RuntimeException和Error),一个方法必须捕捉或者,或者声明抛出方法外

Java任何代码都可抛出异常,如Java环境开发包中代码,自己编写的代码,Java运行时系统,都可以通过throw语句抛出

从方法中抛出的异常都必须使用throws语句

捕获异常通过try-catch语句或者try-catch-finally语句来实现

捕获异常:try、catch和finally

1.try-catch语句

一般格式为

try {

// 可能会发生异常的程序代码

} catch (Type1 id1){

// 捕获并处置try抛出的异常类型Type1

}

catch (Type2 id2){

//捕获并处置try抛出的异常类型Type2

}

关键词try代码块包围的是可能会发生异常的语句,称为监控区域,如果运行中出现异常,则建立异常对象,抛出try代码块,寻找与之匹配的catch子句,运行其异常处理代码

举个栗子:

public class TestEx {

public static void main(String[] args) {

try {

System.out.println(2 / 0);

} catch (ArithmeticException ae) {

System.out.println("程序出错,请与管理员联系!!!");

ae.printStackTrace();

}

}

}

运行结果:

程序出错,请与管理员联系!!!

java.lang.ArithmeticException: / by zero

at TestEx.main(TestEx.java:4)

匹配的原则:如果抛出的异常对象属于catch子句的异常类,或者属于该异常类的子类,则认为生成的异常对象与catch块捕获的异常类型相匹配,而且一旦某个catch捕获到匹配的异常类型,将进入异常处理代码。

一经处理结束,就意味着整个try-catch语句结束,其他的catch子句不再有匹配和捕获异常类型的机会,所以对于有多个catch子句的异常程序而言,应该尽量将捕获底层异常类的catch子句放在前面,同时尽量将捕获相对高层的异常类的catch子句放在后面。否则,捕获底层异常类的catch子句将可能会被屏蔽。

public class TestEx {

public static void main(String[] args) {

int[] intArray = new int[3];

try {

for (int i = 0; i <= intArray.length; i++) {

intArray[i] = i;

System.out.println("intArray[" + i + "] = " + intArray[i]);

System.out.println("intArray[" + i + "]模 " + (i - 2) + "的值: "

+ intArray[i] % (i - 2));

}

} catch (ArrayIndexOutOfBoundsException e) {

System.out.println("intArray数组下标越界异常。");

} catch (ArithmeticException e) {

System.out.println("除数为0异常。");

}

System.out.println("程序正常结束。");

}

}

运行结果

intArray[0]=0

intArray[0]模 -2的值: 0

intArray[1] = 1

intArray[1]模 -1的值: 0

intArray[2] = 2

除数为0异常。

程序正常结束。

例中程序运行过程中ArithmeticException异常类型是先行匹配的,因此执行相匹配的catch语句

另外,RuntimeException异常类包括运行时各种常见的异常,ArithmeticException类和ArrayIndexOutOfBoundsException类都是它的子类。因此,RuntimeException异常类的catch子句应该放在最后面,否则可能会屏蔽其后的特定异常处理或引起编译错误

2.try-catch-finally语句

一般格式为

try {

// 可能会发生异常的程序代码

} catch (Type1 id1) {

// 捕获并处理try抛出的异常类型Type1

} catch (Type2 id2) {

// 捕获并处理try抛出的异常类型Type2

} finally {

// 无论是否发生异常,都将执行的语句块

}

finally语句表示无论是否出现异常都会执行的语句

finally块在以下几种情况不会执行:

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

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

3、程序所在的线程死亡

4、关闭CPU

3.try-catch-finally语法规则

1、try之后必须添加catch块或finally块,可同时接两种块,但至少有一个,若catch代码块和finally代码块同时存在,则finally代码块必须位于catch代码块后面

2、try-catch-finally结构可嵌套

3、在 try-catch-finally 结构中,可重新抛出异常

4、在try代码块中定义的变量的作用域为try代码块,在catch代码块和finally代码块中不能访问该变量

4.try-catch-finally语句块执行顺序

1、*try没有捕获到异常时,*try块中逐句执行,跳过catch块,执行finally块和之后的语句

2、try块捕获到异常,catch语句块里无处理此异常,此异常会抛给JVM处理,finally语句块执行,但finally语句块之后的语句不会执行

3、try块捕获到异常,并在catch块中能够处理此异常,在try快中按照顺序执行,出现异常时,跳到catch块,找到与之对应的处理程序,其它的catch块不会被执行,try块中出现异常后的语句也不会执行,catch执行完之后,执行finally块中语句,最后执行finally块之后的语句

c91c061a4bf2787679767a225c2f3570.png

另外还有一个问题就是

有return的情况下try catch finally的执行顺序

抛出异常

前面已经提到,任何代码都可以抛出异常,如Java环境开发包中代码,自己编写的代码,Java运行时系统,都可以通过Java的throw语句抛出异常,从方法中抛出的任何异常都必须使用throws子句

1、throws抛出异常

如果一个方法可能会出现异常,但是没有能力处理这种异常,则可以在方法声明处用throws子句来声明抛出异常

throws语句用在方法定义时声明该方法要抛出的异常类型,如果抛出的是Exception异常类型,则该方法被声明为抛出所有的异常,抛出多个异常可使用逗号分割

语法格式为

method() throws Exception1,Exception2,..,ExceptionN

{

}

方法名后的Exception1,Exception2,..,ExceptionN为声明要抛出的异常列表,当方法抛出异常列表的异常时,方法将不对这些类型及其子类类型的异常做处理而抛向该方法的调用

void f() throws FileNotFoundException,IOException{

FileInputStream in = new FileInputStream("myfifle.txt");

int b;

b = in.read();

while (b!=-1){

System.out.println((char) b);

b = in.read();

void f2(){ //或者再throws出去

try {

f();

} catch (FileNotFoundException e) {

e.printStackTrace();

}catch(IOException e){

e.printStackTrace();

}

一般主方法不抛出异常,用try-catch-finally语句块处理

throws抛出异常的规则:

1、如果是不可查异常(unchecked exception),那么可以不使用throws关键字来声明要抛出的异常,编译时能通过,但在运行时会被抛出

2、如果一个方法可能出现可查异常(checked exception),要么用try-catch语句捕获,要么用throws关键字抛出,否则编译错误

3、当抛出了异常,该方法的调用者才必须处理或者重新抛出该异常,若调用者无力处理,则继续抛出

4、若覆盖一个方法,则不能声明与覆盖方法不同的异常,声明的异常必须是被覆盖方法所声明异常的同类或者子类

再举个栗子:

public class TestEx {

void method1() throws IOException{} //合法

//编译错误,必须捕获或声明抛出IOException

void method2(){

method1();

}

//合法,声明抛出IOException

void method3()throws IOException {

method1();

}

//合法,声明抛出Exception,IOException是Exception的子类

void method4()throws Exception {

method1();

}

//合法,捕获IOException

void method5(){

try{

method1();

}catch(IOException e){…}

}

//编译错误,必须捕获或声明抛出Exception

void method6(){

try{

method1();

}catch(IOException e){throw new Exception();}

}

//合法,声明抛出Exception

void method7()throws Exception{

try{

method1();

}catch(IOException e){throw new Exception();}

}

}

如何判断一个方法是否可能会出现异常

1、方法中有throw语句

2、调用了其他方法,其他方法用throws子句声明抛出某种异常

2、throw抛出异常

throw关键字总是出现在函数体中,用来抛出一个Throwable类型的异常。程序会在throw语句后终止,后面的语句执行不到,然后在包含它的所有try块中(可能在上层调用函数中)从里向外寻找含有与其匹配的catch子句的try块

异常是异常类的实例对象,可以创建异常的实例对象通过throw语句抛出,例如抛出一个IOException类的异常对象:

throw new IOException 但抛出的只能是Throwable类或者其子类的对象

如果抛出了检查异常,则还应该在方法头部声明方法可能抛出的异常类型,该方法的调用者也必须检查处理抛出的异常,如果所有方法都层层上抛获取的异常,最终会由JVM处理

3、Throwable类常用的方法

catch关键字后面括号中的Exception类型的参数e:Exception就是try代码块传递给catch的代码块的变量类型,e就是变量名

catch代码块中 e.getMessage() :用于输出错误性质

getCause():返回抛出异常的原因,不存在或未知返回NULL

getMeage():返回异常的消息信息

printStackTrace():对象的堆栈跟踪输出至错误输出流,作为字段 System.err 的值

Java常见异常

runtimeException子类

1、 java.lang.ArrayIndexOutOfBoundsException

数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。

2、java.lang.ArithmeticException

算术条件异常。譬如:整数除零等。

3、java.lang.NullPointerException

空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等

4、java.lang.ClassNotFoundException

找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。

5、java.lang.NegativeArraySizeException 数组长度为负异常

6、java.lang.ArrayStoreException 数组中包含不兼容的值抛出的异常

7、java.lang.SecurityException 安全性异常

8、java.lang.IllegalArgumentException 非法参数异常

IOException

1、IOException 操作输入流和输出流时可能出现的异常。

2、EOFException 文件已结束异常

3、FileNotFoundException 文件未找到异常

其他异常

1、ClassCastException 类型转换异常类

2、ArrayStoreException 数组中包含不兼容的值抛出的异常

3、SQLException 操作数据库异常类

4、NoSuchFieldException 字段未找到异常

5、NoSuchMethodException 方法未找到抛出的异常

6、NumberFormatException 字符串转换为数字抛出的异常

7、StringIndexOutOfBoundsException 字符串索引超出范围抛出的异常

8、IllegalAccessException 不允许访问某类异常

9、InstantiationException 当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常

自定义异常

用户自定义异常类,只需要继承Exception类即可

1、创建自定义异常类

2、在方法中通过throw关键字抛出异常对象

3、如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作

4、在出现异常方法的调用者中捕获并处理异常

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值