Наконец -то ключевое слово в Java обычно используется с блоком Try Catch. Используется для выполнения некоторых операций выпуска ресурсов до конца метода или когда происходит исключение. Недавно я также видел несколько статей в Интернете, обсуждающих порядок выполнения ключевых слов Try Catch, и дается, что наконец -то блок выполняется в конце метода.
Эти взгляды в целом считают, что:
1) Ключевое слово, наконец, выполняется до возвращения к предыдущему методу после оператора возврата программы. Возвращаемое значение будет сохранено во временной области. После того, как окончательный блок будет выполнен, значение временной области будет возвращено.
2) Если в блоке, наконец, есть возвращаемое значение, оно заменит значение, хранящееся во временной области предыдущего блока попыток или поймать в программе.
Но действительно ли проблема такой? Давайте внимательно подумаем об этом. JVM объясняет и выполняет инструкции ByteCode во время выполнения. Когда он выполняет оператор возврата, он не знает, есть ли наконец -то блок потом? Что если нет, наконец, блока? Будь то инструкция по байт -коде или компьютерная инструкция должна быть ясной. JVM не так уж и умный. Та же самая инструкция должна быть ясной и не будет содержать два значения. Следовательно, независимо от того, что такое оператор возврата при запуске, содержимое стека будет выскочено и возвращено в метод вызова.
В то же время мы видим, что книга «глубоко в виртуальную машину Java» дает еще одно объяснение. Когда компилятор Java собирает предложение, наконец, будет получена инструкция JSR. Это приводит к тому, что JVM будет вызван в мини -подпрограмму для выполнения, то есть в конце блока. В то же время оператор return 0 в программе составлен в переменную возврата в стеке в локальную переменную перед вызовом инструкции JSR, а инструкция JSR вызывается, наконец -то блок выполняется, и наконец -то блок возвращает. Когда возвращаемое значение в локальной переменной вносится в стек, выполняется инструкция Ireturn, возвращаемое значение появляется из стека и возвращается в метод вызова. Здесь возвращаемое значение сохраняется в локальной переменной перед выполнением инструкции JSR, потому что исключение может произойти во время выполнения блока, наконец, или есть также возвратные значения. Только таким образом может быть обеспечена согласованность окончательного выполнения программы. Поскольку в течение некоторого времени была написана «углубление виртуальной машины Java», реализация и версия компилятора JVM, используемого автором, также отличается от той, которая обсуждается в этой статье. Таким образом, после тестирования существует небольшая разница в генерации байткодов для различных реализаций компилятора или версий разных компиляторов для одной и той же программы. Если вы заинтересованы, вы можете взглянуть на байт -код, сгенерированный положением, наконец, в этой книге.
Генерация Bytecode в этой статье составлена и сгенерирована версией компилятора Oracle JDK8U-25.
Давайте посмотрим на пример ниже.
1. Наконец -то пример: Положите пример:
public Class nightStest {public static void main (string [] args) {int r = test (); System.out.println (r); } public static int test () {try {System.out.println ("try"); // вернуть 1/0; возврат 0; } catch (Exception e) {System.out.println ("Exception"); возврат 100; } наконец {System.out.println ("наконец -то"); }}}Используйте оператор return 0 в блоке try, и результат работы программы:
пытаться
Окончательно
0
Используйте оператор RETURN 1/0 в блоке TRY, и результат запуска программы:
Исключение
Окончательно
100
Фактически, благодаря выполнению результатов, мы видим, что блока, наконец, выполняется после других операторов до возврата в блоке Try или Catch. Другими словами, порядок написания программы не соответствует нашему порядку выполнения, потому что JVM интерпретирует и выполняет Bytecode, поэтому нам нужно посмотреть, как компилятор Java собирает этот код, и посмотреть, как выглядит сгенерированным байт -кодом.
2. Часть байт -кода, сгенерированная программой: (Пожалуйста, обратитесь к инструкции Java Bytecode)
Public Static Int Test (); Descriptor: () I Флаги: ACC_PUBLIC, ACC_STATIC CODE: Stack = 2, локалы = 2, args_size = 0 0: getStatic #20 // Поле java/lang/system.out: ljava/io/printStream; 3: LDC #36 // String Try 5: Invokevirtual #38 // Метод Java/io/printStream.println: (ljava/lang/string;) v 8: getStatic #20 // Полевая java/lang/system.out: ljava/io/printStream; 11: LDC #41 // Строка Наконец 13: Invokevirtual #38 // Метод Java/io/printStream.println: (ljava/lang/string;) v 16: iconst_0 17: returner 18: Store_0 19: GetStatic #20 // Field Java/Lang/System.out: ljava/i -idtstream; 22: LDC #43 // String Exception 24: Invokevirtual #38 // Метод Java/io/printStream.println: (ljava/lang/string;) V 27: getStatic #20 // Полевой java/lang/system.out: ljava/io/printStream; 30: LDC #41 // Строка Наконец 32: Invokevirtual #38 // Метод Java/io/printStream.println: (ljava/lang/string;) v 35: bipush 100 37: return 38: store_1 39: getStatic #20 // Field Java/lang/System.out: ljava/io/io printStream; 42: LDC #41 // Строка Наконец 44: Invokevirtual #38 // Метод Java/io/printStream.println: (ljava/lang/string;) v 47: aload_1 48: aThrow Exception Таблица: из целевого типа 0 8 18 класс Java/lang/Exception 0 8 38 Любое 18 27 38 Таблица: из целевого типа 0 8 18 класс Java/Lang/Exception 0 8 38.
Из красной части мы видим, что строки 10 и 11 соответствуют инструкциям с оператором блока, 16 и 17 соответствуют возврату 0 инструкций после других операторов на блоке Try, до возврата. 19 и 20 соответствуют окончательному блокам инструкции 21 и 22 соответствуют инструкциям возврата 100 операторов. Пойдя по другим заявлениям и до возвращения, мы видим, что за ними все происходит, что компилятор Java сделал все это для нас. Что касается исключений, которые возникают в программе, JVM найдет соответствующее местоположение адреса для обработки исключений из таблицы исключений для выполнения.
Поэтому мы можем сделать вывод, что заявления в блоках, наконец, будут вставлены компилятором Java перед оператором возврата блока Try Block и после других утверждений. Здесь нет подпрограмм для генерации вызовов JSR здесь. Вот почему, независимо от того, выполняет ли он блок Try или выполняет блок подъема, наконец -то блок будет выполнен до возвращения метода.
Вышеупомянутый всесторонний анализ времени исполнения Java, наконец, является всем контентом, которым я делюсь с вами. Я надеюсь, что вы можете дать вам ссылку, и я надеюсь, что вы сможете поддержать Wulin.com больше.