Java异常学习四:Thinking In Java and Effective Java关于异常的一些描述

一.Thinking In Java

  1. 发现错误的最佳时期是编译期间,然而编译期间并不能找出所有数据,余下的问题必须在运行期间解决。
  2. switch case语句里如果throw Exception的话是不需要break的。
  3. 异常处理理论上有两种基本模型。终止模型,java和c++支持的模型,将假设错误非常关键,一旦异常被抛出,就表明错误已经无法挽回,也不能继续执行;恢复模型,遇到错误不能抛出异常,而是调用方法来修正错误。
  4. 尽量不要捕获RuntimeException,但还是可以在代码中抛出RuntimeException类型的异常。
  5. 如果一个方法只申明了异常,但并没有在方法体抛出任何异常,调用此方法的方法是没有异常可以捕获的。
  6. 丢失异常:1.不使用异常链;2.从finally语句返回。
    package com.jyz.study.jdk.exception;
    
    import java.io.IOException;
    
    /**
     * 丢失异常
     * @author JoyoungZhang@gmail.com
     *
     */
    public class LostException {
    	
    	public static void test1() {
    		try{
    			throw new IOException();
    		}finally{
    			return;
    		}
    	}
    	
    	public static void test2() throws IOException {
    		try{
    			throw new IOException();
    		}finally{
    			System.out.println(1);
    		}
    	}
    	
    	public static void main(String[] args) {
    		test1();
    		try {
    			test2();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    
    }
    
    
    控制台:
    1
    java.io.IOException
    	at com.jyz.study.jdk.exception.LostException.test2(LostException.java:22)
    	at com.jyz.study.jdk.exception.LostException.main(LostException.java:31)
     
  7. 异常的限制:1.父类异常大于等于子类异常,子类要么不抛,要么抛出父类异常或父类异常的子异常。2.如果一个对象声明为父类引用时,调用此对象的方法,抛出父类里声明的异常;如果一个对象声明为是自己引用时,调用此对象的方法,当然抛出自己声明的异常,跟父类无关。3.异常声明不是方法签名的一部分,方法签名由方法名字和参数个数及类型组成,所以异常声明不能作为重载的判断标准。4.构造器可以抛出任何异常,而不必理会父类构造器抛了什么异常。
  8. 在创建需要清理的对象之后,立即进入try-finally块清理此对象。
  9. 异常匹配顺序:找出最近的异常;子类的对象也可以匹配其父类的处理程序。找到匹配的后,不再继续查找。
  10. 异常的重要准则是只有在你知道如何处理的情况下才捕获异常。重要目标是把错误处理的代码同错误发生的地点相分离。举个列子service-dao两层,在dao里产生了SQLException我无需处理直接抛出,到了service层,我知道要将其转换成自己的业务异常。

二.Effective Java 

  1. 基于异常的模式:用try catch然后忽略异常的手段来达到你想要的目的。
  2. 异常应该只用于异常的情况下,它们永远不应该用于正常的控制流。对此我不赞同。、
  3. 对可恢复的情况使用受检异常,对编程错误使用运行时异常。何为可恢复的情况,是指不改变代码的基础上,这个异常情况是可以恢复的,比喻IOExcepion可能是网络的问题,解决了网络,代码就能继续运行下去了;何为错误,当然指不能恢复的啦,比喻从你控制范围之外传递进来的null引用,所以,此类异常都是程序员的问题,作为程序员,应该在代码中进行必要的检查。
  4. 异常类越少,意味着内存印迹就越小,装载这些类的时间开销也越少。
  5. 异常转译:高层的实现应该捕获低层的异常,同时抛出可以按照高层抽象进行解释的异常。异常链就是一种特殊的异常转译形式,高层异常可以通过getCause来获得低层的异常。
  6. 异常的细节信息应该包含所有的对该异常有贡献的参数和域的值。比喻IndexOutOfBoundsException应该包含lowerBound,upperBound,Index三个参数。遗憾的是Java平台里并没有广泛的使用这种做法,而是全部清一色的简单继承了下父Exception。
  7. 失败原子性:失败的方法调用应该使对象保持在调用前的状态。如果没有size==0的判断,可能导致size域同之前的不一致。
    	public Object pop(){
    	    if(size == 0){
    		throw new EmptyStackException();
    	    }
    	    Object result = elements[--size];
    	    //...
    	}
     

二.try catch finally break continue return 

    准则 

  1. finally一般情况总会执行,无论在try块里return break continue。除了调用System.exit(0)方法,该方法终止java虚拟机进程。
  2. try块里return之前,finally会被执行。
  3. return语句会把后面的值复制到一份用来返回,如果return的是基本类型的,finally里对变量的改动将不起效果,如果return的是引用类型的,改动将可以起效果。执行顺序:将要return时调用jsr指令----->finally代码块,finally代码块最后执行ret指令----->继续return。
  4. finally里的return语句会把try块里的return语句效果给覆盖掉。finally语句里的return,break,continues,抛出异常,finally子句结尾处的ret指令永远不会执行,不会在去调用finally的地方了。

      我们需要做的是

  1. 最好把return放到方法尾而不要在try里return。
  2. 如果非要的话:不要在try块和finally块里都包含return;如果在try块里return, 则不要在finally块里操作被return的变量。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值