Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Есть ли смысл использовать final в блоке catch


Автор: Royan 22.10.2008, 14:55
Задались с коллегами вопроом, а есть ли смысл писать вот так

Код

try {
  // code
} catch (final XxxxException e) {
  // do exception handling
}


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

Автор: LSD 22.10.2008, 15:17
А шоб було! smile 

Хотя я себе смутно представляю ситуацию, когда это реально может потребоваться. Конечно для final переменных JIT может провести дополнительную оптимизацию, но в случае с Exception, это как мёртвому припарки.

Автор: SoulKeeper 22.10.2008, 17:32
Ну вот приспичит Вам написать код

Код

...
}catch(Exception e){
new Thread(new Runnable(){

public void run(){
//do something with exception
}

});
}


и без final переменной не обойтись ;)

Автор: Samotnik 22.10.2008, 17:40
SoulKeeper,  я чета  не понимаю, зачем ?  
Можеш обьяснить ?  smile   Пажааалста  smile 

Автор: LSD 22.10.2008, 17:57
Цитата(Samotnik @  22.10.2008,  18:40 Найти цитируемый пост)
Можеш обьяснить ?

Запусти компиляцию и компилятор тебе объяснит.

Автор: Platon 22.10.2008, 20:02
Цитата(LSD @  22.10.2008,  16:17 Найти цитируемый пост)
Конечно для final переменных JIT может провести дополнительную оптимизацию

А я читал, что это миф. final дает только возможность, приведенную SoulKeeper и просто, чтоб в процессе написания кода случайно не переопределить переменную.

Автор: Samotnik 22.10.2008, 20:06
вот блин, я почему то читал  finally  а  не final  smile  smile 
надо домой ити  smile 

Автор: HappyCoder 22.10.2008, 20:35
Цитата(Platon @ 22.10.2008,  20:02)
Цитата(LSD @  22.10.2008,  16:17 Найти цитируемый пост)
Конечно для final переменных JIT может провести дополнительную оптимизацию

А я читал, что это миф. final дает только возможность, приведенную SoulKeeper и просто, чтоб в процессе написания кода случайно не переопределить переменную.

Это не миф. Просто новые JVM уже настолько умные, что им необязательно знать, final ли переменная или нет.

Автор: w1nd 23.10.2008, 13:07
Цитата(HappyCoder @  22.10.2008,  20:35 Найти цитируемый пост)
Просто новые JVM уже настолько умные, что им необязательно знать, final ли переменная или нет.

Отношение, конечно, верное - с каждой версией они всё умнее и умнее. Но насчёт настолько-умности-уже-сейчас - к сожалению, миф. GC далеко не всегда соображает, когда можно удалить объект - обнуление локальной ссылки перед выходом из метода ему сильно помогает. JIT создаёт неоптимальный код - элементарные оптимизации арифметических операций не выполняются. Качество оптимизации на этапе компиляции ниже плинтуса - в нижеследующем примере с автобоксингом всё очень и очень печально. Наконец, никто не отменял рефлексию smile 

Код
   /* 
    * Исходный код
    */

    public int sum(Integer... numbers) {
        Integer sum = 0;
        
        for (Integer number : numbers) {
            sum += number;
        }
        
        return sum;
    }

   /* 
    * После компиляции
    */

    public int sum(Integer numbers[]) {
        Integer sum = Integer.valueOf(0);
        Integer numbersCopy[] = numbers;
        int count = numbersCopy.length;
        for(int i = 0; i < count; i++) {
            Integer number = numbersCopy[i];
            sum = Integer.valueOf(sum.intValue() + number.intValue());
        }

        return sum.intValue();
    }


А пользительность модификатора final для параметров и локальных переменных (сюда же относятся исключения, декларированные в catch) - это действительно МИФ. Правда в том, что при использовании достаточно умного (!) компилятора этот модификатор не повредит (!) результату. Для каждого final-параметра в соответствующем классе будет зарезервировано финальное поле со всеми втекающими и вытекающими.

Добавлено через 1 минуту и 52 секунды
Кстати, ещё капля дёгтя - не удаляется мёртвый код.

Добавлено через 5 минут и 1 секунду
Да, собственно, главную мысль не сформулировал: модификатор final для методов, полей и параметров и локальных переменных - это, считайте, разные модификаторы smile 

Автор: Platon 24.10.2008, 11:48
Цитата(w1nd @  23.10.2008,  14:07 Найти цитируемый пост)
Кстати, ещё капля дёгтя - не удаляется мёртвый код.

а я замечал, что простейшие ветки отсекает:
Код

if (DEBUG)
    System.out.println("debug mode only");


Не декомпилировал, но то, что строки "debug mode only" в байткоде не было косвено указывает на отсечение этой ветки.

Автор: w1nd 24.10.2008, 15:12
Цитата(Platon @  24.10.2008,  11:48 Найти цитируемый пост)
а я замечал, что простейшие ветки отсекает

Да, это единственное, что оно умеет отсекать.

Автор: Royan 27.10.2008, 13:29
Исходя из всего вышесказанного напрашивается такой вывод. Было бы здорово в будущих версиях java видеть все локальные переменные (в т.ч. параметры методов) константами по умолчанию, а те из них, что должны изменяться следует помечать как переменные, например, вот так:

Код

for (variable int i = 0; i < 10; i++) 


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

Автор: Platon 27.10.2008, 14:02
Цитата(Royan @  27.10.2008,  14:29 Найти цитируемый пост)
Исходя из всего вышесказанного напрашивается такой вывод.

что-то не напрашивается.

Цитата(Royan @  27.10.2008,  14:29 Найти цитируемый пост)
все локальные переменные (в т.ч. параметры методов) константами по умолчанию

нет, здорово бы не было.



Автор: LSD 27.10.2008, 14:14
Цитата(Royan @  27.10.2008,  14:29 Найти цитируемый пост)
Было бы здорово в будущих версиях java видеть все локальные переменные (в т.ч. параметры методов) константами по умолчанию, а те из них, что должны изменяться следует помечать как переменные, например, вот так:

Жесть.

Автор: Royan 28.10.2008, 02:01
PlatonLSD
Хорошо почему нет?

Автор: Keyo 28.10.2008, 11:00
Вот почитайте, интересная статья, кое что и про final есть
http://blogs.sun.com/vmrobot/entry/%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C_%D0%BF%D0%B0%D0%BC%D1%8F%D1%82%D0%B8_java

Согласен с LSD, особого смысла делать в блоке try/catch, final Exception особого смысла нет... и вообще Platon прав, мне кажется что это прежде всего средство для обеспечения большей прозрачности кода

А вот еще интересная статья, почти в тему...
http://www.ibm.com/developerworks/ru/library/j-jtp1029/index.html

Автор: w1nd 29.10.2008, 12:48
Такое ощущение возникает, что люди не воспринимают того, к чему не готовы. Русским языком написал, что final для локальных переменных и параметров - это мало что вообще не про константы, так ещё и имеет непосредственное влияние на генерируемый код, а не на какую-то там прозрачность чего-то... нет, не понимают smile 

Автор: Keyo 30.10.2008, 10:06
w1nd, да вы правы, преклоняю пред вами колени, великий гуру и да не коснется гнев ваш меня

Автор: w1nd 30.10.2008, 12:51
Цитата(Keyo @  30.10.2008,  10:06 Найти цитируемый пост)
w1nd, да вы правы, преклоняю пред вами колени, великий гуру и да не коснется гнев ваш меня

Усерднее, усерднее бейте челом, а то треска не слышно smile

Автор: SuperFly 1.11.2008, 12:35
Цитата(w1nd @  23.10.2008,  14:07 Найти цитируемый пост)
обнуление локальной ссылки перед выходом из метода ему сильно помогает.

А что насчет обнуления перекрестных ссылок? К примеру, окно закрываем, и надо бы всю рудиментную сеть взаимосвязанных объектов. Как это оформить? сделать метод подчистки, который обнуляет ссылки и вызывает подобные методы подчистки подчиненных объектов?

Автор: w1nd 1.11.2008, 13:18
Цитата(SuperFly @  1.11.2008,  12:35 Найти цитируемый пост)
Как это оформить? сделать метод подчистки, который обнуляет ссылки и вызывает подобные методы подчистки подчиненных объектов?

Я так и делал. Очень помогало.

Автор: SuperFly 1.11.2008, 13:43
Цитата(w1nd @  1.11.2008,  13:18 Найти цитируемый пост)
Я так и делал. Очень помогало.

Почему в прошедшем времени? Теперь не делаете?

Автор: w1nd 1.11.2008, 17:29
Цитата(SuperFly @  1.11.2008,  13:43 Найти цитируемый пост)
Почему в прошедшем времени? Теперь не делаете?

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

Автор: Royan 5.11.2008, 11:45
Цитата(w1nd @  23.10.2008,  10:07 Найти цитируемый пост)
обнуление локальной ссылки перед выходом из метода ему сильно помогает

Хотелось бы понять как вы это проверяли? То есть это был тест (если тест то какой) или просто наблюдение на сложном GUI?

Автор: w1nd 6.11.2008, 13:03
Цитата(Royan @  5.11.2008,  11:45 Найти цитируемый пост)
Хотелось бы понять как вы это проверяли? То есть это был тест (если тест то какой) или просто наблюдение на сложном GUI?

Глядя на показания Windows Task Manager. SUN JVM в клиентском режиме сразу же высвобождает память, занятую чем-то гарантированно недостижимым. И это был специальный тест. Поясню - память в любом случае освобождается или используется повторно, но если не обнулять ссылки явно, это действо откладывается сборщиком "на потом". Тест очень простой - создаём большой массив чего-нибудь в обработчике нажатия на кнопочку и либо обнуляем перед выходом из него, либо не обнуляем.

Автор: Keyo 6.11.2008, 13:44
хм, интересно. а как это оформить? просто тупо в конце каждого метода обнулять ссылки?

Автор: w1nd 6.11.2008, 15:56
Цитата(Keyo @  6.11.2008,  13:44 Найти цитируемый пост)
просто тупо в конце каждого метода обнулять ссылки?

Можно в местах, где возможно вызывать какой-нить dispose, чистить ссылки на объекты, которые точно не понадобятся. Можно вообще ничего не делать - рано или поздно реализуют JVM, в которой будет суперумный сборщик мусора, которому не понадобятся подсказки... smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)