尝试Catch,最后使用Return语句

时间:2014-03-14 14:52:26

标签: java return try-catch finally

在准备Java认证的过程中,我看到了一些棘手的代码。

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

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

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并且它会被持久化。

任何解释都会有所帮助。

我明白这是编写得很糟糕的代码,正确思想中的任何人都不应该写这样的东西。

2 个答案:

答案 0 :(得分:1)

在第一个示例中finally没有更改任何内容,因为10已经标记为要在catch语句中返回的值。如果您将return添加到finally块或从return删除catch并仅保留最后一个返回语句,那么您将获得值20.最重要的是您这里只返回值而不是引用。

另一方面,在第二个示例中,StringBuilder是可变的,returnVal是对象的引用。比returnVal值和#34; 10"被标记为要返回的值,但是在main方法finally中打印returnVal的值之前,执行块并且它会从" 10"中更改returnVal的值。至" 1010"。与在main方法中打印returnVal相比,您将获得此对象的最新值,即" 1010"。它的工作方式与此类似,因为getStringBuilder返回StringBuilder的引用,该引用是可变的。

答案 1 :(得分:1)

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

尝试运行以下代码,以便更好地说明。

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的标识哈希:1152321476 即将返回:10 catch块中的returnVal的标识哈希:1152321476 最后的returnVal的标识哈希:2116610996 现在返回值:20 在Main:10

returnVal的标识哈希:814397217 即将返回:10 catch块中的returnVal的标识哈希:814397217 现在返回值:1010 最后的returnVal的标识哈希:814397217 在Main:1010

returnVal的标识哈希:1660743788 1660743788 catch块中的returnVal的标识哈希:1660743788 即将返回:10 最后的returnVal的标识哈希:1660743788 现在返回值:20 20