•异常:在Java语言中,将程序执行中发生的不正常情况称为“异常”。
•Java中的异常用于处理非预期的情况,如文件没找到,网络错误,非法的参数
Java程序运行过程中所发生的异常事件可分为两类:
Error: JVM系统内部错误、资源耗尽等严重情况 ,这个是没法处理的,在编程的时候应该避免出现
Exception:其它因编程错误或偶然的外在因素导致的一般性问题,可以捕获或抛出
例如:
--除数为零
–空指针访问
–试图读取不存在的文件
–网络连接中断
一、Java在处理异常的时候是通过创建异常对象来处理的,我们称抓抛处理;
异常对象的理解:在Java虚拟机运行的时候,如果产生上述中的某个异常,Java虚拟机会自动生成一个对象,这个对象是属于Throwable类(可抛出的)这个类有两个直接子类Error和Exception,我们只讨论Exception类对象的抛出和捕获
Exception又有各种子类体现各种异常,如RuntimeException(运行时错误)
程序有异常,Java虚拟机会自动生成对象,我们可以用catch来捕获它
try,catch,finally的使用
try
{
执行的语句,可能会含有错误
}catch(异常对象){
处理异常的操作
}finally{
不论有无异常,都会执行这个花括号内的语句
}
例1:
public class Test01 {
public static void main(String[] args) {
String []arr={"haha","hehe","heihei"};
for(int i=0;i<5;i++)
System.out.println(arr[i]);
}
public static void main(String[] args) {
String []arr={"haha","hehe","heihei"};
for(int i=0;i<5;i++)
System.out.println(arr[i]);
}
}
执行结果
haha
hehe
heihei
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at Test_01.Test01.main(Test01.java:7)
系统提示越界异常,并给出了范围应该在3以内
hehe
heihei
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at Test_01.Test01.main(Test01.java:7)
系统提示越界异常,并给出了范围应该在3以内
进行try,catch捕获:
public class Test01 {
public static void main(String[] args) {
String []arr={"haha","hehe","heihei"};
try {
for(int i=0;i<5;i++) //循环到5,数组长度为3;所欲越界异常
System.out.println(arr[i]);
}catch(Exception e){
System.out.println("捕获到了异常");
}finally {
System.out.println("不论怎样,就是打印这句话");
}
}
}
执行结果:
public class Test01 {
public static void main(String[] args) {
String []arr={"haha","hehe","heihei"};
try {
for(int i=0;i<5;i++) //循环到5,数组长度为3;所欲越界异常
System.out.println(arr[i]);
}catch(Exception e){
System.out.println("捕获到了异常");
}finally {
System.out.println("不论怎样,就是打印这句话");
}
}
}
执行结果:
haha
hehe
heihei
捕获到了异常
不论怎样,就是打印这句话
hehe
heihei
捕获到了异常
不论怎样,就是打印这句话
二、异常的传递(异常链)
如果一个方法内抛出异常,该异常会被抛到调用方法中。如果异常没有在调用方法中处理,它继续被抛给这个调用方法的调用者。这个过程将一直继续下去,直到异常被处理。如果所有的调用者都没处理,一个异常回到main()方法,并且main()也不处理,则程序运行终止。
例2:
public class Test02 {
int tt=9;
public static void main(String[] args) {
a();
}
private static void a() {
// TODO Auto-generated method stub
b();
}
private static void b() {
c();
}
private static void c() {
Test02 aa=new Test02();
aa=null;
System.out.println(aa.tt); //此处有一个空指针异常
}
}
int tt=9;
public static void main(String[] args) {
a();
}
private static void a() {
// TODO Auto-generated method stub
b();
}
private static void b() {
c();
}
private static void c() {
Test02 aa=new Test02();
aa=null;
System.out.println(aa.tt); //此处有一个空指针异常
}
}
执行结果:从下往上看
Exception in thread "main" java.lang.NullPointerException //找到错误啦,是个空指针错误
at Test02.Test02.c(Test02.java:18) // c中18行有错误
at Test02.Test02.b(Test02.java:13) //略
at Test02.Test02.a(Test02.java:10) //往a()方法里找,是在第十行调用b()时有错误
at Test02.Test02.main(Test02.java:6) //在main方法里第6行有错误,第六行是调用a()的语句
at Test02.Test02.c(Test02.java:18) // c中18行有错误
at Test02.Test02.b(Test02.java:13) //略
at Test02.Test02.a(Test02.java:10) //往a()方法里找,是在第十行调用b()时有错误
at Test02.Test02.main(Test02.java:6) //在main方法里第6行有错误,第六行是调用a()的语句
注:异常链的实际应用很少,发生异常时候逐层上抛不是个好注意,
上层拿到这些异常又能奈之何?而且异常逐层上抛会消耗大量资源,
因为要保存一个完整的异常链信息.
三、自定义异常(异常转译)
在实际开发中,api给出的异常种类是远远不够的,我们需要自己定义一些异常类来表示特定的异常,这些自定义的异常类通过继承api中的异常类来扩展;
例3
class MyException extends RuntimeException {
@Override
public String getMessage() {
// TODO Auto-generated method stub
return "这是我自定义的运行时异常";
}
}
public String getMessage() {
// TODO Auto-generated method stub
return "这是我自定义的运行时异常";
}
}
在上面的代码中,我们自己定义了一个MyException继承了运行异常,并重写了getMessage(),下面写一个运行时的异常,并使它转换成我的异常:
public class Test02 {
int tt=9;
public static void main(String[] args) {
testException();
}
public static void testException(){
try{
int i = 1/0;
}catch(Exception e){ //此处捕获的任何exception异常,我都在catch中抛出我自己定义的异常;
throw new MyException();
}
}
int tt=9;
public static void main(String[] args) {
testException();
}
public static void testException(){
try{
int i = 1/0;
}catch(Exception e){ //此处捕获的任何exception异常,我都在catch中抛出我自己定义的异常;
throw new MyException();
}
}
}
执行结果:(抛出了我自己写的异常)
Exception in thread "main" Test02.MyException: 这是我自定义的运行时异常
at Test02.Test02.testException(Test02.java:13)
at Test02.Test02.main(Test02.java:6)
at Test02.Test02.testException(Test02.java:13)
at Test02.Test02.main(Test02.java:6)