Java 尝试Catch并最终使用Return语句

Java 尝试Catch并最终使用Return语句,java,return,try-catch,finally,Java,Return,Try Catch,Finally,在我准备Java认证的过程中,我看到了两段如此棘手的代码 这里末尾的返回值是:10,但最后被调用,它将returnval修改为20 有人能解释为什么会这样吗?是因为捕获的范围不同吗?或者我在这里遗漏了什么 class MultipleReturn { int getInt() { int returnVal = 10; try { String[] students = {"Harry", "Paul"}; System.out.println(students[5]);

在我准备Java认证的过程中,我看到了两段如此棘手的代码

这里末尾的返回值是:10,但最后被调用,它将returnval修改为20

有人能解释为什么会这样吗?是因为捕获的范围不同吗?或者我在这里遗漏了什么

class MultipleReturn {
int getInt() {
int returnVal = 10;
try {
     String[] students = {"Harry", "Paul"};
     System.out.println(students[5]);
    }
catch (Exception e) {
    System.out.println("About to return :" + returnVal);
    return returnVal;
    }
finally {
    returnVal += 10;
    System.out.println("Return value is now :" + returnVal);
    }
return returnVal;
}

public static void main(String args[]) {
       MultipleReturn var = new MultipleReturn();
       System.out.println("In Main:" + var.getInt());
      }
}
另一个后续代码是:

class MultipleReturn {
  StringBuilder getStringBuilder() {
  StringBuilder returnVal = new StringBuilder("10");
  try {
      String[] students = {"Harry", "Paul"};
      System.out.println(students[5]);
  }
  catch (Exception e) {
      System.out.println("About to return :" + returnVal);
      return returnVal;
  }
  finally {
     returnVal.append("10");
     System.out.println("Return value is now :" + returnVal);
  }
  return returnVal;
  }

  public static void main(String args[]) {
    MultipleReturn var = new MultipleReturn();
    System.out.println("In Main:" + var.getStringBuilder());
  }
}
这里的输出是1010,这是有意义的,因为最终修改了returnval并将其持久化

任何解释都会有帮助


我知道这是一个写得很糟糕的代码,任何头脑正常的人都不应该写这样的东西。

在第一个示例中,
最后,
没有任何变化,因为10已经标记为要在
catch
语句中返回的值。如果将
return
添加到
finally
块或从
catch
中删除
return
并只保留最后一条return语句,则会得到值20。最重要的是,这里只返回值,不返回引用


另一方面,在第二个示例中,StringBuilder是可变的,returnVal是对对象的引用。然后,返回值为“10”的returnVal被标记为要返回的值,但在主方法内部打印returnVal的值之前,
最后执行
块,它将returnVal的值从“10”更改为“1010”。如果在main方法中打印returnVal,则会得到该对象的最新值,即“1010”。它是这样工作的,因为
getStringBuilder
返回StringBuilder的引用,它是可变的。

这里有很多事情,但我认为它归结起来是,在getStringBuilder版本中,returnVal对象是可变的,并且正如您所观察到的,在返回“1010”的finally子句中,相同的对象发生了变化。另一方面,当您将10添加到finally子句中的整数时,返回的值与返回的值在内存中的地址不同

试着运行下面的代码来更好地说明

class MultipleReturn {
  int getInt() {
    int returnVal = 10;

    System.out.println("Identiy hash of returnVal: " + System.identityHashCode(returnVal));
    try {
      String[] students = { "Harry", "Paul" };
      System.out.println(students[5]);
    } catch (Exception e) {
      System.out.println("About to return :" + returnVal);
      System.out.println("Identiy hash of returnVal in catch block: " + System.identityHashCode(returnVal));
      return returnVal;
    } finally {
      returnVal += 10;
      System.out.println("Identiy hash of returnVal in finally: " + System.identityHashCode(returnVal));
      System.out.println("Return value is now :" + returnVal);
    }
    return returnVal;
  }

  StringBuilder getStringBuilder() {
    StringBuilder returnVal = new StringBuilder("10");

    System.out.println("Identiy hash of returnVal: " + System.identityHashCode(returnVal));
    try {
      String[] students = { "Harry", "Paul" };
      System.out.println(students[5]);
    } catch (Exception e) {
      System.out.println("About to return :" + returnVal);
      System.out.println("Identiy hash of returnVal in catch block: " + System.identityHashCode(returnVal));
      return returnVal;
    } finally {
      returnVal.append("10");
      System.out.println("Return value is now :" + returnVal);
      System.out.println("Identiy hash of returnVal in finally: " + System.identityHashCode(returnVal));
    }
    return returnVal;
  }


  static class MutableInteger {
    public int val;

    @Override
    public String toString() {
      return Integer.toString(val);
    }
  }


  MutableInteger getMutableInt() {
    MutableInteger returnVal = new MutableInteger();
    returnVal.val = 10;
    System.out.println("Identiy hash of returnVal: " + System.identityHashCode(returnVal));
    System.out.println(System.identityHashCode(returnVal));
    try {
      String[] students = { "Harry", "Paul" };
      System.out.println(students[5]);
    } catch (Exception e) {
      System.out.println("Identiy hash of returnVal in catch block: " + System.identityHashCode(returnVal));
      System.out.println("About to return :" + returnVal);
      return returnVal;
    } finally {
      returnVal.val += 10;
      System.out.println("Identiy hash of returnVal in finally: " + System.identityHashCode(returnVal));
      System.out.println("Return value is now :" + returnVal);
    }
    return returnVal;
  }  

  public static void main(String args[]) {
    MultipleReturn var = new MultipleReturn();
    System.out.println("In Main:" + var.getInt());
    System.out.println();
    System.out.println("In Main:" + var.getStringBuilder());
    System.out.println();
    System.out.println(var.getMutableInt());
  }
}
结果:

returnVal的Identiy散列:1152321476 即将返回:10 catch块中returnVal的Identiy散列:1152321476 finally中returnVal的Identiy散列:2116610996 返回值现在是:20 总数:10

returnVal的Identiy散列:814397217 即将返回:10 catch块中returnVal的Identiy散列:814397217 返回值现在是:1010 returnVal的Identiy散列在finally:814397217中 总数:1010

returnVal的Identiy散列:1660743788 1660743788 catch块中returnVal的Identiy散列:1660743788 即将返回:10 finally中returnVal的Identiy散列:1660743788 返回值现在是:20
20

这让事情变得更清楚了。谢谢你,我没有想到这方面。谢谢你指出这一点。