Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18

TRICKS: Что вернёт метод?

17.02.2014, 13:39. Показов 3819. Ответов 42

Студворк — интернет-сервис помощи студентам
начинаем серию постов TRICKS по фишкам JVM и компилятора, вопросы для самообразования, не более

просьба не компилировать, а попробовать подумать что вернёт метод

Java
1
2
3
4
5
6
7
8
9
10
    static String dubleReturn() {
        while (true) {
            try {
                return "foo";
            } finally {
                break;
            }
        }
        return "boo";
    }
а после того как скомпилите и увидите результат, прошу объяснить почему именно так

ps: вопрос чисто академический, поэтому не стоит нести чушь про то что так писать негоже
1
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.02.2014, 13:39
Ответы с готовыми решениями:

TRICKS: Что нам грядущая 8-чка готовит
допустим у нас есть List l = new ArrayList() { { for (int i = 0; i < 10; i++) { ...

Пример, когда метод Thread.isAlive() вернёт false
Приведите, пожалуйста, два примера. Такие, что бы в первом main thread при вызове на ней метода isAlive(); вернула false, а во втором...

Reflection: что вернет getField.getInt(null)?
У Хорстмана наткнулся на следующую строку: return JOptionPane.class.getField(s).getInt(null); И все не могу сообразить, что оно вернуть...

42
 Аватар для IVIakCollideR
40 / 40 / 14
Регистрация: 26.12.2013
Сообщений: 309
17.02.2014, 16:24
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от mutagen Посмотреть сообщение
просьба не компилировать, а попробовать подумать что вернёт метод
метод вернул boo как никак, и это довольно логично c его стороны, потому что стековый фрейм общий для всех значение в данном случае, а финалли сработает любой ценой, попросту после отработкт финалли части имеем return foo, но оно затирается вызовом return boo, поскольку я уже сказал - место для строчной константы одно на двоих
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
17.02.2014, 16:26  [ТС]
Цитата Сообщение от IVIakCollideR Посмотреть сообщение
попросту после отработкт финалли части имеем return foo
не имеем, так как после окончания finally указатель ДОЛЖЕН вернуться на первый return что нам и демонстрирует код
Java
1
2
3
4
5
6
7
static String tryFinally() {
        try {
            return "foo";
        } finally {
            System.out.println("finally");
        }
    }
по вашей "имеем" мы должны оказаться за блоком try finally и ничего не вернуть
0
46 / 36 / 15
Регистрация: 05.02.2014
Сообщений: 140
17.02.2014, 16:35
Цитата Сообщение от IVIakCollideR Посмотреть сообщение
метод вернул boo как никак, и это довольно логично c его стороны, потому что стековый фрейм общий для всех значение в данном случае, а финалли сработает любой ценой, попросту после отработкт финалли части имеем return foo, но оно затирается вызовом return boo, поскольку я уже сказал - место для строчной константы одно на двоих
Вся фишка в break.

Добавлено через 7 минут
можно еще так сделать:
Java
1
2
3
4
5
6
7
8
9
10
11
12
    static String dubleReturn() {
        String str = "doo";
        while (true) {
            try {
                return str;
            } finally {
                str += " boo";
                //break;
            }
        }
        //return str;
    }
и убрать комментирование
0
 Аватар для IVIakCollideR
40 / 40 / 14
Регистрация: 26.12.2013
Сообщений: 309
17.02.2014, 16:38
Цитата Сообщение от mutagen Посмотреть сообщение
Код Java(TM) 2 Platform Standard Edition 5.0
1
2
3
4
5
6
7
static String tryFinally() {
* * * * try {
* * * * * * return "foo";
* * * * } finally {
* * * * * * System.out.println("finally");
* * * * }
* * }
по вашей "имеем" мы должны оказаться за блоком try finally и ничего не вернуть
нет, все правильно, у вас же 1 ретурн в этом коде, значит возвращает именно он, но в прошлом примере было 2 ретурна, второй обязан выполниться потому что инструкция должна бить прочитана после блока финалли и если там ничего нет, - управление передается к первому ретурну, а если там что то еще есть, как в нашем случае - второй ретурн, то он выполняется и перезаписывает значение новым - своим, поскольку они оба занимают место для 1 константы.

если вставить System.exit(1); перед ретурном(вторым) в первой задачке, то можно увидеть что на данный момент будет в стеке, а именно - foo/
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
17.02.2014, 16:46  [ТС]
Цитата Сообщение от RomanovD Посмотреть сообщение
Вся фишка в break.
это не фишка а баг и в байткоде удаляется первый ретурн, чё бы вы не наделали с переменными его просто нет )

Добавлено через 6 минут
Цитата Сообщение от IVIakCollideR Посмотреть сообщение
второй обязан выполниться потому что инструкция должна бить прочитана после блока финалли и если там ничего нет
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
   
 for (int i = 0; i < 10; i++) {
            System.out.println(goodDoubleRet());
        }
 
  static int goodDoubleRet() {
        Random r = new Random();
        try {
            if (r.nextInt(2) == 1) {
                return 1;
            }
        } finally {
            System.out.println("fin");
        }
        return 2;
    }
попробуйте скомпилить, странно да - имеем 2 ретурна, но если в 1 в ифке тру то до второго не добираемся, хотя файнал пашет всегда
0
3 / 3 / 1
Регистрация: 18.09.2013
Сообщений: 19
17.02.2014, 17:03
Цитата Сообщение от mutagen Посмотреть сообщение
это не фишка а баг и в байткоде удаляется первый ретурн, чё бы вы не наделали с переменными его просто нет )

Добавлено через 6 минут

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
   
 for (int i = 0; i < 10; i++) {
            System.out.println(goodDoubleRet());
        }
 
  static int goodDoubleRet() {
        Random r = new Random();
        try {
            if (r.nextInt(2) == 1) {
                return 1;
            }
        } finally {
            System.out.println("fin");
        }
        return 2;
    }
попробуйте скомпилить, странно да - имеем 2 ретурна, но если в 1 в ифке тру то до второго не добираемся, хотя файнал пашет всегда
Ничего странного я не вижу. Все пашет как и должно пахать.
Если бы работало как вы описываете по спекам, то действительно был бы баг (до спек не добрался, но боюсь у вас не верная интерпретация), потому что в этом случае мы полностью игногрировали бы break.
Я считаю, что разработчики java все сделали логично. Приоритет оставлен за последним оператором.
0
46 / 36 / 15
Регистрация: 05.02.2014
Сообщений: 140
17.02.2014, 17:06
это не фишка а баг и в байткоде удаляется первый ретурн, чё бы вы не наделали с переменными его просто нет )
Наверное он удаляется по той же причине, по которой удаляется return в следующем коде:
Java
1
2
3
4
static String dubleReturn() {
        if (false) return "foo";
        return "doo";
}
Java
1
2
3
4
5
6
7
static dubleReturn()Ljava/lang/String;
   L0
    LINENUMBER 6 L0
    LDC "doo"
    ARETURN
    MAXSTACK = 1
    MAXLOCALS = 0
Мы просто никогда его не выполним, поэтому его и нет.
0
 Аватар для IVIakCollideR
40 / 40 / 14
Регистрация: 26.12.2013
Сообщений: 309
17.02.2014, 17:12
Цитата Сообщение от mutagen Посмотреть сообщение
странно да 2 ретурна, но если в 1 в ифке тру то до второго не добираемся
а вы про брейк не забыли в файнали? именно он и передает управление на следующую строку после цыкла,
в первом примере думаю было бы то же самое без брейка
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
17.02.2014, 18:09  [ТС]
Цитата Сообщение от RomanovD Посмотреть сообщение
Наверное он удаляется по той же причине, по которой удаляется return в следующем коде:
именно - это называется работа оптимизатора, и в этом случае всё ок

Цитата Сообщение от IVIakCollideR Посмотреть сообщение
а вы про брейк не забыли в файнали? именно он и передает управление на следующую строку после цыкла,
я вижу вам всё равно и логика и отсутствие в байткоде ретурна - только бы доказать своё мнение )
хорошо что тут есть Skipy который показал что там в байткоде, но я уверен и без этого нашлись бы люди которые утверждали бы что затереть успешный ретурн это нормально )))
думаю на этом можно эту темку завершить, но не переключайте канал, я ещё подкину задачек )
0
 Аватар для IVIakCollideR
40 / 40 / 14
Регистрация: 26.12.2013
Сообщений: 309
17.02.2014, 19:32
Цитата Сообщение от mutagen Посмотреть сообщение
только бы доказать своё мнение )
есть такой косяк, заранее прошу понять и простить если что
Цитата Сообщение от mutagen Посмотреть сообщение
хорошо что тут есть Skipy который показал что там в байткоде, но я уверен и без этого нашлись бы люди которые утверждали бы что затереть успешный ретурн это нормально )))
я выразил свою точку зрения, то как это работает - весьма логично, многие ответили так, да и результат работы программы = boo, Вопрос был ведь не как правильно/неправильно, а конкретным -
Цитата Сообщение от mutagen Посмотреть сообщение
что вернёт метод
.
В следующий раз будем глубже углубляться в сторону логики)
0
 Аватар для KuKu
1563 / 1041 / 94
Регистрация: 17.04.2009
Сообщений: 2,995
17.02.2014, 19:56
Цитата Сообщение от IVIakCollideR Посмотреть сообщение
а конкретным -
Тут два варианта - выбор не велик
0
3 / 3 / 1
Регистрация: 18.09.2013
Сообщений: 19
18.02.2014, 12:31
Для интереса проверил, а как же реализуют этот код другие языки.

Delphi не компилиться и выдает ошибку
E2126 Cannot BREAK, CONTINUE or EXIT out of a FINALLY clause

C# то же не компилиться
Control cannot leave the body of a finally clause

Как видно здесь даже не пытались разрешить конфликтную ситуацию, что игнорировать return или break,
просто запретили.

Добавлено через 12 минут
Цитата Сообщение от mutagen Посмотреть сообщение
не имеем, так как после окончания finally указатель ДОЛЖЕН вернуться на первый return что нам и демонстрирует код
Java
1
2
3
4
5
6
7
static String tryFinally() {
        try {
            return "foo";
        } finally {
            System.out.println("finally");
        }
    }
по вашей "имеем" мы должны оказаться за блоком try finally и ничего не вернуть
Это совершенно разные ситуации. В вашем случае в finally есть оператор влияющий на порядок выполнения (break). А в случае выше таких операторов нет.

Как по вашему должет работать код?

Java
1
2
3
4
5
6
7
while (true) {
            try {
                return "foo";
            } finally {
                return "too";
            }
        }
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
18.02.2014, 13:28  [ТС]
Цитата Сообщение от vladimirsky Посмотреть сообщение
Как по вашему должет работать код?
выполнится первым тот что в файнале и выполнит ретурн "тоо", это же очевидно - так как файнал выполняется первы всегда, никто у него ничего не перехватит
Цитата Сообщение от vladimirsky Посмотреть сообщение
В вашем случае в finally есть оператор влияющий на порядок выполнения (break).
это же не должно влиять на успешный ретурн, не так ли или должно, как вы считаете ?
логично ли что операция с низким приоритетом брейк влияет на операцию с высоким приоритетом ретурн?
0
3 / 3 / 1
Регистрация: 18.09.2013
Сообщений: 19
18.02.2014, 15:07
Цитата Сообщение от mutagen Посмотреть сообщение
это же не должно влиять на успешный ретурн, не так ли или должно, как вы считаете ?
логично ли что операция с низким приоритетом брейк влияет на операцию с высоким приоритетом ретурн?
Я не слышал, что есть приоритет операторов перехода в java.
По-моему работает принцип, кто последний тот и прав.
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
18.02.2014, 15:22  [ТС]
ок - не совсем верная формулировка, не приоритет, а скажем вернее так:
уже выполнившаяся операция return прерывается операцией break
как же быть с этим?

Java
1
2
3
4
5
6
7
8
9
10
11
12
static void tst() {
        while (true) {
            if (1 == 1) {
                System.out.println(1);
                return ;
            }
            System.out.println(3);
            break;
        }
        System.out.println(2);
        return;
    }
кто тут последний?
0
3 / 3 / 1
Регистрация: 18.09.2013
Сообщений: 19
18.02.2014, 15:41
Цитата Сообщение от mutagen Посмотреть сообщение
ок - не совсем верная формулировка, не приоритет, а скажем вернее так:
уже выполнившаяся операция return прерывается операцией break
как же быть с этим?

Java
1
2
3
4
5
6
7
8
9
10
11
12
static void tst() {
        while (true) {
            if (1 == 1) {
                System.out.println(1);
                return ;
            }
            System.out.println(3);
            break;
        }
        System.out.println(2);
        return;
    }
кто тут последний?
Первый оператор return. До остальных код просто не добирается.

На счет "выполнившаяся" операция return. То здесь она еще не выполнилась. Иначе мы уже бы покинули функцию. Еще надо выполнить finally, но мы ЯВНО меняем ход выполнения программы.
А если бы в finally был exception, как поступать в этом случае. По вашему return вроде как и выполнен.

Я понимаю, что Вы хотите мне показать, но считаю теперешнее поведение кода правильным.

BTW. За TRICKS рассылку, спасибо. Очень помогает для "шлифовки" знаний.
0
 Аватар для verylazy
462 / 462 / 71
Регистрация: 26.02.2013
Сообщений: 1,263
18.02.2014, 16:10
я тут нашел кое что на сайте оракла
и там прямо в первом абзаце получите ответ
The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs. But finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated.
То есть получается finally и был задуман для перехвата внезапно сделать оп оп return;
0
 Аватар для KuKu
1563 / 1041 / 94
Регистрация: 17.04.2009
Сообщений: 2,995
18.02.2014, 16:17
Имхо, это не совсем то. Он задуман сделать оп-оп даже если тогда, когда был return. А не делать return самому. По-хорошему надо было запретить эти return/break в finally. Поздно спохватились скорее всего, а тут и обратную совместимость надо оставить.
0
 Аватар для verylazy
462 / 462 / 71
Регистрация: 26.02.2013
Сообщений: 1,263
18.02.2014, 16:24
Я именно это и имел ввиду просто выразился непонятно.
У меня эклипс вообще ругается на break в finally
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
18.02.2014, 16:32  [ТС]
Цитата Сообщение от vladimirsky Посмотреть сообщение
считаю теперешнее поведение кода правильным.
Цитата Сообщение от verylazy Посмотреть сообщение
when the try block exits.
это ключевая нескладуха, так как ретурн был в трай и этот блок отработал успешно и без экцепов по всем нормам человеческого языка ))) По всем соглашениям и докам после отработки финализации, мы обязаны были вернуть управление на return, так как он уже был выполнен и ожидает возврата из файнала
Цитата Сообщение от verylazy Посмотреть сообщение
try block exits
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
18.02.2014, 16:32
Помогаю со студенческими работами здесь

Что вернет length для двумерного массива?
я Java не изучаю.но анализируя один код на Java у меня возник вопрос. допустим задан двухмерный массив int mass какое значение...

Передать в метод "что-то", что бы метод мог в это "что-то" записать матрицу неизвестной размерности
Опишу суть проблемы подробнее. Есть метод, который умножает две матрицы, мне бы хотелось, что бы метод принимал в параметрах: 1....

Что вернёт метод простого класса
доброго времени суток. Имеем простой класс. import android.accounts.Account; import android.accounts.AccountManager; import...

Что вернет функция
Что вернет функция, проверяющая баланс скобок, если она принимает как параметр такую строку: ((х+y/z+у+(z/(y+z))-((0*z)-3) ...

Что вернет функция
Здравствуйте! Я вот С не знаю вообще, подскажите пожалуйста выполнится ли while при таком условии if (array_size == 0) return (0);...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Опции темы

Новые блоги и статьи
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2. Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
Отчёт о спецтехнике находящейся в ремонте
Maks 20.04.2026
Отчёт из решения ниже размещен в конфигурации КА2. Задача: отобразить спецтехнику, которая на данный момент находится в ремонте. Есть нетиповой документ "Заявка на ремонт спецтехники" который. . .
Памятка для бота и "визитка" для читателей "Semantic Universe Layer (Слой семантической вселенной)"
Hrethgir 19.04.2026
Сгенерировано для краткого описания по случаю сборки и компиляции скелета серверного приложения. И пусть после этого скажут, что статьи сгенерированные AI - туфта и не интересно. И это не реклама -. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru