解决方案 »

  1.   

    throw e肯定是抛给调用者。由于除数为0属于Runtime Exception,编译器在编译时是不会管的,所以如果division方法中如果没有catch这种异常,声明中是不需要有throws的。声明中的throws只是用来告诉上层调用者以及编译器该方法将会有异常抛出,它本身并不会导致异常的抛出。
    finally的意思是无论try块中有没有发生异常finally块中的代码都会执行。return 0;如果放在finally外,那么try中异常后,catch住然后throw e;方法就中止执行了,则不会执行return 0;反之,return 0;放在finally内,try中异常后,catch住然后throw e;方法中止执行抛出异常前会先执行finally块中的语句,而finally中又使方法正常返回。所以就导致了异常没被抛出。我不知道我说清楚没有有点绕
      

  2.   

    throw e肯定是抛给调用者。由于除数为0属于Runtime Exception,编译器在编译时是不会管的,所以如果division方法中如果没有catch这种异常,声明中是不需要有throws的。声明中的throws只是用来告诉上层调用者以及编译器该方法将会有异常抛出,它本身并不会导致异常的抛出。
    finally的意思是无论try块中有没有发生异常finally块中的代码都会执行。return 0;如果放在finally外,那么try中异常后,catch住然后throw e;方法就中止执行了,则不会执行return 0;反之,return 0;放在finally内,try中异常后,catch住然后throw e;方法中止执行抛出异常前会先执行finally块中的语句,而finally中又使方法正常返回。所以就导致了异常没被抛出。我不知道我说清楚没有有点绕
    基本明白了,还有一点不太明白, 就是return  在finally 里: 既然 在catch中 throw e 了,那么调用者不应该catch到吗?虽然说我在finally里是正常return了,但是因为之前我已经throw e了。(或者 成功return后 会将之前的throw e 怎样怎样,深层的原理我也不懂) 这点可否再解释详细一点?! 不胜感谢啊。或者说 方法divsion应该设计成 void类型更为合理一些。
      

  3.   

    抛出的时候再离开代码块之前要运行finally中的代码
      

  4.   

    throw e肯定是抛给调用者。由于除数为0属于Runtime Exception,编译器在编译时是不会管的,所以如果division方法中如果没有catch这种异常,声明中是不需要有throws的。声明中的throws只是用来告诉上层调用者以及编译器该方法将会有异常抛出,它本身并不会导致异常的抛出。
    finally的意思是无论try块中有没有发生异常finally块中的代码都会执行。return 0;如果放在finally外,那么try中异常后,catch住然后throw e;方法就中止执行了,则不会执行return 0;反之,return 0;放在finally内,try中异常后,catch住然后throw e;方法中止执行抛出异常前会先执行finally块中的语句,而finally中又使方法正常返回。所以就导致了异常没被抛出。我不知道我说清楚没有有点绕
    基本明白了,还有一点不太明白, 就是return  在finally 里: 既然 在catch中 throw e 了,那么调用者不应该catch到吗?虽然说我在finally里是正常return了,但是因为之前我已经throw e了。(或者 成功return后 会将之前的throw e 怎样怎样,深层的原理我也不懂) 这点可否再解释详细一点?! 不胜感谢啊。或者说 方法divsion应该设计成 void类型更为合理一些。
    结论:
    1、不管有木有出现异常,finally块中代码都会执行;
    2、当try和catch中有return时,finally仍然会执行;
    3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
    4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。参考地址:http://blog.csdn.net/kavensu/article/details/8067850
      

  5.   

    throw e肯定是抛给调用者。由于除数为0属于Runtime Exception,编译器在编译时是不会管的,所以如果division方法中如果没有catch这种异常,声明中是不需要有throws的。声明中的throws只是用来告诉上层调用者以及编译器该方法将会有异常抛出,它本身并不会导致异常的抛出。
    finally的意思是无论try块中有没有发生异常finally块中的代码都会执行。return 0;如果放在finally外,那么try中异常后,catch住然后throw e;方法就中止执行了,则不会执行return 0;反之,return 0;放在finally内,try中异常后,catch住然后throw e;方法中止执行抛出异常前会先执行finally块中的语句,而finally中又使方法正常返回。所以就导致了异常没被抛出。我不知道我说清楚没有有点绕
    基本明白了,还有一点不太明白, 就是return  在finally 里: 既然 在catch中 throw e 了,那么调用者不应该catch到吗?虽然说我在finally里是正常return了,但是因为之前我已经throw e了。(或者 成功return后 会将之前的throw e 怎样怎样,深层的原理我也不懂) 这点可否再解释详细一点?! 不胜感谢啊。或者说 方法divsion应该设计成 void类型更为合理一些。
    好吧我们来讲讲原理首先感谢http://icyfenix.iteye.com/blog/857722这篇博文解释了字节码的意义然后是我自己做的一个实验实验有两个样本,一个在finally中有return我们称为hasreturn,一个在finally中没有return我们称为noreturn。代码如下:
    hasreturn:try {
        throw new IOException("joking");
    } catch (IOException e) {
        throw e;
    } finally {
        return;
    }noreturn:
    try {
        throw new IOException("joking");
    } catch (IOException e) {
        throw e;
    } finally {
        a = 1;  //a为try块外定义的一个int型变量初始值为0
    }
    然后编译后的字节码如下:
    hasreturn:         2: new           #2                  // class java/io/IOException
             5: dup           
             6: ldc           #3                  // String joking
             8: invokespecial #4                  // Method java/io/IOException."<init>":(Ljava/lang/String;)V
            11: athrow        
            12: astore_2      
            13: aload_2       
            14: athrow        
            15: astore_3      
            16: returnnoreturn:         2: new           #2                  // class java/io/IOException
             5: dup           
             6: ldc           #3                  // String joking
             8: invokespecial #4                  // Method java/io/IOException."<init>":(Ljava/lang/String;)V
            11: athrow        
            12: astore_2      
            13: aload_2       
            14: athrow        
            15: astore_3      
            16: iconst_1      
            17: istore_1      
            18: aload_3       
            19: athrow对比可见两份字节码几乎一致,差别从偏移16开始。简单说一下同部分的几个athrow和astore。偏移11处athrow的是最初new的IOException,之后发现有handler(也就是catch部分),又在偏移12处astore回栈中;偏移14处athrow对应的是catch里面的throw e;,之后发现还有个finally再次在偏移15处astore回去。(具体的推荐看看上面说的那篇文章)
    hasreturn在偏移16处直接就return了,而noreturn中在偏移19处还有一次athrow操作。也就是说finally中有return的时候,异常是被存入了栈中,但是最终未被抛给调用者。