java异常类java
java.lang.Throwablec++
方法:程序员
getMessage(); 得到异常描述编程
printStackTrance(); 打印异常堆栈数组
关于Throwable网络
** StackTraceElement。一个final类,表明栈轨迹中的元素,一个异常可能有多个元素。测试
一.打印栈轨迹的方法this
- 主动调用Throwable对象的printStackTrace()=printStackTrace(System.err),printStackTrace(PrintStream),printStackTrace(PrintWriter)中的其中一个。
- 若是一个Exception没有被处理,直接在main方法后面throws,程序退出前将调用异常的printStackTrace()方法,最终是Exception in thread "main" + printStackTrace()
栈轨迹设计
- 栈轨迹显示了"把你带到异常抛出的地点"。
- 上面三个方法调用this.getOurStackTrace()得到栈轨迹;同时Throwable提供了public的方法getStackTrace()得到栈轨迹(实际返回getOurStackTrace().clone())。
- getStackTrace()将返回栈轨迹中元素所构成的数组,其中每个元素都是一帧。元素0是栈顶元素,栈顶元素为调用序列里的最后一个方法,栈底元素是第一个方法。
fillInStackTrace方法调试
- native fillInStackTrace()方法将返回一个Throwable对象,它是经过把当前调用栈信息填入原来那个异常对象儿创建的,因此返回的仍是原来的异常。
- 调用此方法的那一行将成为异常新的发生地,有关原来异常发生点的信息会丢失。它的效果等价于捕获一个异常后,从新抛出另一种异常。二者不一样的 是,fillInStackTrace后的异常仍是原来的异常(只是少了栈轨迹而已);而从新抛出一个异常的话,彻底跟原异常信息无关了(固然也没有栈轨 迹)。
异常链
- 经常会再捕获一个异常后抛出另一个异常,而且但愿把异常原始信息保存下来,这被称为异常链。
- 在JDK1.4之前,程序员必须本身编写代码来保存原始异常信息,
- 如今全部Throwable的子类子构造器中均可以接受一个cause对象做为参数,这个cause就异常起因,表明着原始异常,即便在当前位置建立并抛出行的异常,也能够经过这个cause追踪到异常最初发生的位置。
- 只有Error,Exception,RunimeException提供了带cause参数的构造器,其余的因此异常就只有经过initCause()来设置cause了。
effective java 和think in java
think in java
- 发现错误的最佳时期是编译期间,然而编译期间并不能找出全部数据,余下的问题必须在运行期间解决。
- switch case语句里若是throw Exception的话是不须要break的。
- 异常处理理论上有两种基本模型。终止模型,java和c++支持的模型,将假设错误很是关键,一旦异常被抛出,就代表错误已经没法挽回,也不能继续执行;恢复模型,遇到错误不能抛出异常,而是调用方法来修正错误。
- 尽可能不要捕获RuntimeException,但仍是能够在代码中抛出RuntimeException类型的异常。
- 若是一个方法只申明了异常,但并无在方法体抛出任何异常,调用此方法的方法是没有异常能够捕获的。
- 丢失异常:1.不使用异常链;2.从finally语句返回。
- 异常的限制:1.父类异常大于等于子类异常,子类要么不抛,要么抛出父类异常或父类异常的子异常。2.若是一个对象声明为父类引用时,调用此对象的方法, 抛出父类里声明的异常;若是一个对象声明为是本身引用时,调用此对象的方法,固然抛出本身声明的异常,跟父类无关。3.异常声明不是方法签名的一部分,方 法签名由方法名字和参数个数及类型组成,因此异常声明不能做为重载的判断标准。4.构造器能够抛出任何异常,而没必要理会父类构造器抛了什么异常。
- 在建立须要清理的对象以后,当即进入try-finally块清理此对象
- 异常匹配顺序:找出最近的异常;子类的对象也能够匹配其父类的处理程序。找到匹配的后,再也不继续查找。
- 异常的重要准则是只有在你知道如何处理的状况下才捕获异常。重要目标是把错误处理的代码同错误发生的地点相分离。举个列子service-dao两层,在 dao里产生了SQLException我无需处理直接抛出,到了service层,我知道要将其转换成本身的业务异常。
effective java
- 基于异常的模式:用try catch而后忽略异常的手段来达到你想要的目的。
- 异常应该只用于异常的状况下,它们永远不该该用于正常的控制流。对此我不赞同。、
- 对可恢复的状况使用受检异常,对编程错误使用运行时异常。何为可恢复的状况,是指不改变代码的基础上,这个异常状况是能够恢复的,比喻 IOExcepion多是网络的问题,解决了网络,代码就能继续运行下去了;何为错误,固然指不能恢复的啦,比喻从你控制范围以外传递进来的null引 用,因此,此类异常都是程序员的问题,做为程序员,应该在代码中进行必要的检查。
- 异常类越少,意味着内存印迹就越小,装载这些类的时间开销也越少。
- 异常转译:高层的实现应该捕获低层的异常,同时抛出能够按照高层抽象进行解释的异常。异常链就是一种特殊的异常转译形式,高层异常能够经过getCause来得到低层的异常。
- 异常的细节信息应该包含全部的对该异常有贡献的参数和域的值。比喻IndexOutOfBoundsException应该包含 lowerBound,upperBound,Index三个参数。遗憾的是Java平台里并无普遍的使用这种作法,而是所有清一色的简单继承了下父 Exception。
- 失败原子性:失败的方法调用应该使对象保持在调用前的状态。若是没有size==0的判断,可能致使size域同以前的不一致。
try catch finally break continue return
准则
finally通常状况总会执行,不管在try块里return break continue。除了调用System.exit(0)方法,该方法终止java虚拟机进程。
try块里return以前,finally会被执行
return语句会把后面的值复制到一份用来返回,若是return的是基本类型的,finally里对变量的改动将不起效果,若是return的是引用 类型的,改动将能够起效果。执行顺序:将要return时调用jsr指令----->finally代码块,finally代码块最后执行ret指 令----->继续return。
finally里的return语句会把try块里的return语句效果给覆盖掉。finally语句里的return,break,continues,抛出异常,finally子句结尾处的ret指令永远不会执行,不会在去调用finally的地方了。
咱们须要作的是
- 最好把return放到方法尾而不要在try里return。
- 若是非要的话:不要在try块和finally块里都包含return;若是在try块里return, 则不要在finally块里操做被return的变量。
两个子类:
Error:仅靠程序自己没法恢复的严重错误,好比内存不足,java虚拟机的方法调用堆栈溢出。
大多数状况下,遇到这样的错误时,程序只有死的份。
StackOverError,OutOfMemoryError
Exception:表示程序能够处理的异常。程序出现异常的时候,应该尽量地处理异常,而且
使得程序恢复运行,而不该该随意停止。
EOFException,FileNotFoundException
RuntimeException异常及其子类:运行时异常
java编译器不会检查它,这种异常没有try catch语句捕获,也没有throw字句抛出,仍是编译经过。
unchecked Exception
运行时异常表示没法让程序恢复运行的异常,致使这种异常的缘由一般是因为执行了错误操做。一旦出现错误操做,建议
终止程序,所以java编译器不检查这种异常。
运行时异常应该尽可能避免,在程序调试阶段,遇到这种异常的时候,正确的作法是改进程序的设计和实现方式,修改程序
中的错误,从而避免这种错误。
若是捕获而且使程序恢复运行不是明智的行为:
1.这种异常一旦发生,损失严重。
2.即便程序恢复运行,也可能会致使程序的业务逻辑错乱,甚至致使更严重的异常,或者获得错误的运行结果。
受检异常,除了RuntimeException及其子类的全部Exception及其子类。
Checked Exception
这种异常要么用try..catch捕获,要么用throw子句声明抛出,不然编译不会经过。
能够处理和修复的异常,若是抛出异常的方法自己不能处理它,那么方法调用者应该去处理,如此递推,知道在某一层能够处理它,
就进行必要的处理,而不至于终止程序。
Error和java运行时异常:
相同:java编译器都不会检查他们,当程序出现错误的时候,都死。
不一样:Error及其子类是由java虚拟机抛出,通常不可拓展。
RuntimeException表示程序代码中的错误,能够自定义。
异常转义和异常链
异常处理原则
1.异常只能用于非正常状况
2.为异常提供文档说明
3.尽量地避免异常
**许多运行时异常是因为代码中的错误引发的,修改代码,改进实现方式
**提供状态测试方法,某种状态下,不适合这种操做,引发异常。
4.保持异常的原则性
**检查方法的参数是否有效,确保异常发生的时候尚未改变初始状态
**恢复代码
**在对象的临时对象上进行操做,当操做成功后,把拷贝的内容复制到原来的对象上
5.避免过于庞大的try代码块
**分段处理
6.在catch子句中指定具体的异常
try{
//code
}catch(Exception e){//code}
**俗话说对症下药,对不一样的异常一般有不一样的处理方式。以上代码意味着对全部异常采用相同的方式,这每每是不现实的。
**会捕获原本应该抛出的运行时异常,掩盖程序中的错误。
7.不要在catch代码块中忽略被捕获的异常
**处理异常:针对异常采起一些行动,好比弥补形成的损失或者给出警告。
**从新抛出异常:若是当前时间或者环境下还不能处理该异常,就应该从新抛出。
**进行异常转译:把原始异常包装成适合当前抽象层的另外一种异常,再将其抛出。
**假如在catch代码块中不能采起任何措施,那么就不要捕获异常,而是用throws子句声明抛出异常。