一个关于Java异常的问题,请大家回答一下

代码如下:
public class ResultTest {

public static void main(String[] args) {
    int test = test(3,5);
    System.out.println(test);

}

public static int test(int x,int y){
    int result = x;
    try{
        if(x < 0 || y < 0){
            return 0;
        }
        result = x + y;
        return result;
    }finally {
        result = x - y;
    }
}

}
请问为什么返回的值是8,而不是-2,请大家帮忙回答一下,谢谢了!

执行顺序是 先执行try里面的语句,再执行finally里面的语句,最后回到try里面的return(finally如果也有return,就执行finally里面的return。)

1、执行完result = x + y; result 变为8
2、执行return result; 这里的操作分两步:
第一步是把result的结果保存起来(如果这里涉及计算,也会执行,得出值,将值存起来)。
第二步是跳转到finally 里面继续执行语句,finally 走完再回到这里 把第一步保存的值返回出去。
3、result = x - y; 刚到这句的时候,result 是8(即上面x+y的结果是带进来了),执行后,result 变为-2,但是没有影响到最后要返回的值。(这里可以看编译出来的class,它是用了两个变量来表示)

img

你如果理解了,可以再做一个扩展,思考下如果返回的是一个对象、一个引用类型,结果又会有什么不同。能加深对Java参数传递的理解

你try的时候已经return了,没有抛出异常不会执行到finally;
而且你的finally没有return,这应该会有编译错误才对,可能是你没有会出现异常的代码,就忽略了finally没有return

public static void main(String[] args) {
    int test = test(3,5);  //调用的函数只接受返回值
    System.out.println(test);
 
}
 
public static int test(int x,int y){
    int result = x;
    try{
        if(x < 0 || y < 0){
            return 0;
        }
        result = x + y;
        return result;   //你这里已经返回了
    }finally {
        result = x - y;
        System.out.println(result);  //你这里可以打印下,result 变成了-2,但是你调用的函数,上面test 已经接收了result=8的返回值
    }
}

懂了吗

这确实是个好问题

这里是kotlin方式实现以及字节码

package demo

import kotlin.jvm.JvmStatic
import demo.Return

object Return {
    @JvmStatic
    fun main(args: Array<String>) {
        val test = test(3, 5)
        println(test)
    }

    fun test(x: Int, y: Int): Int {
        var result = x
        return try {
            result = x + y
            result
        } finally {
            result = x - y
        }
    }
}

编译对的字节码

public final class Return {
   @NotNull
   public static final Return INSTANCE;

   @JvmStatic
   public static final void main(@NotNull String[] args) {
      Intrinsics.checkNotNullParameter(args, "args");
      int test = INSTANCE.test(3, 5);
      System.out.println(test);
   }

   public final int test(int x, int y) {
      int var4;
      try {
         int result = x + y;
         var4 = result;
      } finally {
         int var10000 = x - y;
      }

      return var4;
   }

   private Return() {
   }

   static {
      Return var0 = new Return();
      INSTANCE = var0;
   }
}

从字节码上看到return 的结果是 return var4; 也就是 try { x+ y} 而不是fainal { x -y }

这里需要从编译原理方面理解,和从try catch final 语法上理解。强行解释不好服众啊 ☺