Попробуйте поймать и, наконец, с заявлениями возврата

1

Я видел пару таких хитрых фрагментов кода, когда я готовился к сертификации 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 и сохраняется.

Любое объяснение будет полезно.

я понимаю, что это плохо написанный код, и никто в здравом уме не должен писать ничего подобного.

Теги:
try-catch
return
finally

2 ответа

1
Лучший ответ

В первом примере, finally ничего не изменится, потому что 10 уже помечено как значение, возвращаемое во внутреннюю инструкцию catch. Если вы добавите return к блоку finally или удалите return из catch и оставите только последний оператор возврата, вы получите значение 20. Самое главное, что вы возвращаете только значение, а не ссылку здесь.

С другой стороны, во втором примере StringBuilder является mutable и returnVal является ссылкой на объект. Чем returnVal со значением "10" помечен как возвращаемое значение, но перед тем, как вы напечатаете значение returnVal внутри основного метода, finally блок выполняется и изменяет значение returnVal с "10" на "1010". Затем, если вы напечатаете returnVal внутри основного метода, вы получите последнее значение этого объекта, которое равно "1010". Это работает так, потому что getStringBuilder возвращает ссылку на StringBuilder, которая изменена.

  • 0
    Я не думал об этой стороне. Спасибо за указание на это.
1

Здесь многое происходит, но я думаю, что это сводится к тому, что в версии getStringBuilder объект returnVal изменен и один и тот же объект мутирован в предложении finally, возвращая "1010", как вы заметили. С другой стороны, при добавлении 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: 1152321476 О возврате: 10 Идентификационный хеш returnVal в блоке catch: 1152321476 Идентификатор hash returnVal в конце: 2116610996 Возвращаемое значение сейчас: 20 In Main: 10

Идентичный хеш returnVal: 814397217 О возврате: 10 Идентификационный хэш returnVal в блоке catch: 814397217 Возвращаемое значение сейчас: 1010 Идентификационный хеш returnVal в конце: 814397217 В начало: 1010

Идентичный хеш returnVal: 1660743788 1660743788 Идентификационный хеш returnVal в блоке catch: 1660743788 О возврате: 10 Идентификационный хеш returnVal в конце: 1660743788 Возвращаемое значение сейчас: 20 20

  • 0
    это делает вещи более понятными. Спасибо

Ещё вопросы

Сообщество Overcoder
Наверх
Меню