java基础之异常
Java中的异常处理机制的简单原理和应用:
异常是指java程序运行时(非编译)所发生的非正常情况或错误,与现实生活中的事件很相似,现实生活中的事件可以包含事件发生的时间、地点、人物、情节等信息,可以用一个对象来表示,Java使用面向对象的方式来处理异常,它把程序中发生的每个异常也都分别封装到一个对象来表示的,该对象中包含有异常的信息。
Java对异常进行了分类,不同类型的异常分别用不同的Java类表示,所有异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error和Exception,Error 表示应用程序本身无法克服和恢复的一种严重问题,程序只有死的份了,例如,说内存溢出和线程死锁等系统问题。Exception表示程序还能够克服和恢复的问题,其中又分为系统异常和普通异常,系统异常是软件本身缺陷所导致的问题,也就是软件开发人员考虑不周所导致的问题,软件使用者无法克服和恢复这种问题,但在这种问题下还可以让软件系统继续运行或者让软件死掉,例如,数组脚本越界(ArrayIndexOutOfBoundsException),空指针异常(NullPointerException)、类转换异常(ClassCastException);普通异常是运行环境的变化或异常所导致的问题,是用户能够克服的问题,例如,网络断线,硬盘空间不够,发生这样的异常后,程序不应该死掉。
java为系统异常和普通异常提供了不同的解决方案,编译器强制普通异常必须try..catch处理或用throws声明继续抛给上层调用方法处理,所以普通异常也称为checked异常,而系统异常可以处理也可以不处理,所以,编译器不强制用try..catch处理或用throws声明,所以系统异常也称为unchecked异常。
首先看一下异常的体系:
Throwable: Error :通常出现重大问题如:运行的类不存在或者内存溢出等。 不编写针对代码对其处理
Exception: 在运行时运行出现的一起情况,可以通过try{} catch(){} finally{} Exception和Error的子类名都是以父类名作为后缀。
如RuntimeException
Trowable中的一些常用方法:
getMessage() 获取异常信息,返回字符串。
toString() 获取异常类和异常信息
printStackTrace()获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void
printStackTrace(PrintStream s)
通常用该方法将异常内容保存在日志文件中,以便查阅
异常处理的具体格式:
try { 需要检测的代码; } catch(异常类变量) { 异常处理代码; } finally { 一定会执行的代码; }
注意:Finally代码块只有一种情况不会被执行。就是在之前执行了System.exit(0)。
方法中的其他代码
如果代码正确,那么程序不经过catch语句直接向下运行;
如果代码不正确,则将返回的异常对象和e进行匹配,如果匹配成功,则处理其后面的异常处理代码。
try中如果发现错误,即跳出try块去匹配catch,那么try后面的语句就不会被执行。
一个try可以跟多个catch语句,用于处理不同情况,但是不能将父类型的exception的位置写在子类型的excepiton之前。
在try-catch后还可以再跟一子句finally。其中的代码语句论有没有异常都会被执行(因为finally子句的这个特性,所以一般将释放资源,关闭连接的语句写在里面)。
finally中的代码和try-catch中的代码冲突时,finally中的代码一定会被执行且会忽略try-catch中的代码。但是如果try-catch中有System.exit(0);(虚拟机退出语句),则不会去执行fianlly中的代码。
throws/throw处理方式:
throw 写在方法内,后面跟一个异常对象。
throws 在方法的定义中说明方法可能抛出的异常,后面跟异常类的名字,声明这个方法将不处理异常,把异常交给上一级方法处理。
调用时,调用者不能抛出范围更小的异常。
对于方法a,如果它定义了throws Exception。那么当它调用的方法b返回异常对象时,方法a并不处理,而将这个异常对象向上一级返回,如果所有的方法均不进行处理,返回到主方法,如主方法也不进行处理,则到虚拟机中,程序中止。
如果在方法的程序中有一行throw new Exception(),那么其后的程序不执行,如果没有对这个可能出现的检查结果进行处理,那么程序就会报错。
throws和throw没有必然的联系。
注意:
方法的覆盖中,如果子类的方法抛出的例外是父类方法抛出的例外的父类型,那么编译就会出错:子类无法覆盖父类。
子类抛出的例外或者与父类抛出的例外一致,或者是父类抛出例外的子类型,或者子类型不抛出例外。
如果父类型无throws时,子类型也不允许出现throws。此时只能使用try catch。
自定义异常:
a. 使其继承Exception或者RuntimeException。
b. 写构造器,直接调用父类的构造器
断言(assert):用来调试、测试代码
throw和throw关键字的区别:
throws用在函数上,后面跟异常的类名,可以追加多个异常类名,用逗号分开
throw 用于函数内, 后面跟异常的对象。
异常处理的几个格式:
第一个格式: try { } catch () { }
第二个格式: try { } catch () { } finally {
}
第三个格式: try { } finally { } 注:catch是用于处理异常。如果没有catch就代表异常没有被处理过,如果该异常是检测时异常。那么必须声明。
自定义异常:
如下://自定义异常,用于处理除数为负数的情况:
*/ class FuShuException extends Exception //getMessage(); { private int value;
FuShuException() { super(); } FuShuException(String msg,int value) { super(msg); this.value = value; }
public int getValue() { return value; }
}
class Demo { int div(int a,int b)throws FuShuException { if(b<0) throw new FuShuException("出现了除数是负数的情况------ / by fushu",b);//手动通过throw关键字抛出一个自定义异常对象。
return a/b; } }
class ExceptionDemo3 { public static void main(String[] args)
{ Demo d = new Demo(); try { int x = d.div(4,-9); System.out.println("x="+x); } catch (FuShuException e) { System.out.println(e.toString()); //System.out.println("除数出现负数了"); System.out.println("错误的负数是:"+e.getValue()); }
System.out.println("over");
} }
/* class Throwable { private String message; Throwable(String message) { this.message = message; }
public String getMessage() { return message; } }
使用异常要注意的一些细节:
1.RuntimeException以及其子类如果在函数中被throw抛出,可以不用在函数上声明。
如ArithmeticException,可以通过代码上的处理避免
2.自定义异常时,如果该异常的发生,无法再继续计算,可以让自定义的异常继承RuntimException
3.如果父类抛出多个异常,那么重写(覆盖)方法必须抛出那些异常 的一个子集,不能抛出新的异常。
包与包之间进行访问的总结:
包与包之间进行访问,被访问的包中的类以及类中的成员,需要public修饰。
不同包中的子类还可以直接访问父类中被protected权限修饰的成员。
包与包之间可以使用的权限只有两种,public protected。
public protected default private 同一个类中 ok ok ok ok 同一个包中 ok ok ok 子类 ok ok 不同包中 ok
java.lang : java的核心包 jdk1.2版本以后,该包中的类自动导入。 java.awt: 用于制作图形界面。 java.io:input output 用于操作设备上的数据。 java.util : 这里定义是java的工具类。集合,日期。 java.net:用于网络通讯的。