Re: Какие вы видите проблемы в данном коде?
От: ddocker Россия www.codelab.ru
Дата: 21.05.07 12:16
Оценка: 1 (1) +2 :))) :)
аяй-яй, что же вы так тестовые задания всем интернетом решаете: http://company.yandex.ru/inside/job/dev_bugtracker.xml
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Какие вы видите проблемы в данном коде?
От: Blazkowicz Россия  
Дата: 16.05.07 05:45
Оценка: 3 (1) +2
Здравствуйте, Foror, Вы писали:

F> os.write('\n');


lineSeparator = java.lang.System.getProperty('line.separator');
Re[2]: Какие вы видите проблемы в данном коде?
От: dshe  
Дата: 16.05.07 07:19
Оценка: 4 (2)
Здравствуйте, bolshik, Вы писали:


Что касается 1 и 3. согласен. А вот 2 -- спорный пункт. Совершенно не факт, что в данном случае с IOException'ом нужно обязательно что-то сделать. Вполне возможно, что данный writeLines -- это не единственный утилитный метод, а есть еще readLines и еще некоторое количество подобных методов, которые используются совместно в неком методе performSomeHighLevelWork, который, кстати, может сам может использовать низкоуровневое Java IO API. Поэтому, вместо того, чтобы в каждом из методов типа writeLines писать
        } catch (IOException e) {
            throw new IllegalStateException("Unexpected exception occured during blah-blah-blah", e);
        }

может оказаться проще написать это один раз в performSomeHighLevelWork. Ну и естественно, не забыть cause.
--
Дмитро
Re[8]: Какие вы видите проблемы в данном коде?
От: Donz Россия http://donz-ru.livejournal.com
Дата: 17.05.07 13:16
Оценка: 2 (2)
Здравствуйте, bolshik, Вы писали:

B>>>Да, теоретически возможно, но, имхо, в данном случае преимущество обработки такой ситуации меньше, чем увеличение объема и уменьшение читабельности кода, необходимого для этого.

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

B>На самом деле, я сразу не сообразил, что ошибки-то в этом нет (в случае оборачивания в unchecked; как альтернатива можно использовать логирование). Кинуть эксепшн в обоих случаях (и при write(), и при close()) не получится ==> надо выбирать что-то одно. Я выбираю вариант, когда эксепшн из close() перезатирает эксепшн из write(). Эта ситуация мне не нравится меньше, чем когда наверх летит эксепшн от write(), и остается открытый поток.


Ты же поток не закроешь, если кинешь исключение о том, что не получилось его закрыть.
Если код, например, построить таким образом:
OutputStream out = new smth.getOutputStream();
try
{
  out.write( data );
}
finally
{
  try
  {
    out.close();
  }
  catch( Exception ignored ){}
}

То будет выполнена попытка закрытия поток, и наверху мы получим "правильное исключение".
Ещё можно ввести флажок, а каким образом вызван блок finally: нормально или из-за исключения, и, анализируя флажок, принимать решение, подавлять исключение, возникшее при закрытии потока, или выбрасывать его наверх. Только это уже как-то мудрено получается. Я обычно использую приведёный код.
Re[2]: Какие вы видите проблемы в данном коде?
От: Blazkowicz Россия  
Дата: 16.05.07 06:44
Оценка: 1 (1) +1
Здравствуйте, bolshik, Вы писали:

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

B> throw new IllegalStateException("Unexpected exception occured during writing to file. File: "

B> + file.getAbsolutePath() + ", data to write: " + Arrays.toString(lines));

Эй, а cause? Так по логам нельзя будет восстановить причину ошибки.
Re[4]: Какие вы видите проблемы в данном коде?
От: . Великобритания  
Дата: 16.05.07 16:13
Оценка: +2
Дмитрий В wrote:

>> > if(fileWriter!=null)

> .>Вот это лишнее, имхо.
>
> Эт точно, надо было так написать
А чем так плохо?
     public static void writeLines(File file, String[] lines) throws IOException {
         PrintStream fileWriter = new PrintStream(file);
         try {
             for (String line : lines) {
                 fileWriter.println(line);
             }
         } finally {
             fileWriter.close();
         }
     }
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[8]: Какие вы видите проблемы в данном коде?
От: LeonidV Ниоткуда http://vygovskiy.com
Дата: 17.05.07 10:59
Оценка: +2
Здравствуйте, bolshik, Вы писали:

B> И на текущем этапе моей девелоперской жизни я вижу только минусы checked exceptions перед unchecked.

Не согласен. Зачастую уровень, который кидает исключение, сам не может с ним справится. Самый простой и наглядный пример — открытие файла, спрятанное в вызовах и затребованное пользователем. Тут логично вынести обработку исключения поближе к пользователю.
http://jvmmemory.com — простой способ настройки JVM
Re[4]: Какие вы видите проблемы в данном коде?
От: Donz Россия http://donz-ru.livejournal.com
Дата: 17.05.07 09:28
Оценка: 12 (1)
Здравствуйте, bolshik, Вы писали:

MAP>>Что-то не понял для чего так оборачивать метод writeLinesImpl и почему не кидать IOException наерх?


B>Потому что IOException — checked exception.


А в чём проблема то? Там, наверху, в зависимости от того, что и куда пишем, сами разберутся, что с исключением делать.

По коду. Если возникло исключение во время работы методов write, то, возможно, будет исключение и при попытке закрыть поток, но так как закрытие находится в блоке finally, то исключение от попытки закрытия потока подавит "настоящее" исключение, то есть возможно потеряется истинная причина исключительной ситуации.
Re[4]: Какие вы видите проблемы в данном коде?
От: aefimov Россия
Дата: 16.05.07 06:31
Оценка: 1 (1)
Здравствуйте, b_manvelyan, Вы писали:

_>Ой, а можно чуть подробнее, гед надо указывать. Спасибо.


Я чуток напутал — не $n, а %n:

<?xml version='1.0' encoding='ISO-8859-1' ?>
<!DOCTYPE log4j:configuration SYSTEM "file:./log4j.dtd">

<log4j:configuration>
   <appender name="CONSOLE-WARN" class="org.apache.log4j.ConsoleAppender">
     <param name="target" value="System.err"/>
     <layout class="org.apache.log4j.PatternLayout">
       <param name="ConversionPattern" value="[%7r] %6p - %14.14c - %m%n"/>
     </layout>
     <filter class="org.apache.log4j.varia.LevelRangeFilter">
       <param name="LevelMin" value="DEBUG"/>
     </filter>
   </appender>

   <appender name="FILE" class="org.apache.log4j.RollingFileAppender">
      <param name="MaxFileSize" value="1Mb"/>
      <param name="MaxBackupIndex" value="3"/>
      <param name="file" value="log/app.log"/>
      <layout class="org.apache.log4j.PatternLayout">
         <param name="ConversionPattern" value="%d [%7r] %6p - %14.14c - %m%n"/>
      </layout>
   </appender>

   <root>
     <priority value="DEBUG"/>
     <appender-ref ref="FILE"/>
   </root>
</log4j:configuration>
Re: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 16.05.07 06:38
Оценка: 1 (1)
Здравствуйте, Foror, Вы писали:

F>
F>void writeLines(File file, String[] lines, String encoding) throws IOException {
F>    OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
F>    try {
F>        for (String line: lines) {
F>            os.write(line.getBytes(encoding));
F>            os.write('\n');
F>        }
F>    } finally {
F>        os.close();
F>    }
F>}
F>




Итого:

    public void writeLines(File file, String encoding, String ... lines) throws IllegalStateException {
        try {
            writeLinesImpl(file, encoding, lines);
        } catch (IOException e) {
            throw new IllegalStateException("Unexpected exception occured during writing to file. File: "
                    + file.getAbsolutePath() + ", data to write: " + Arrays.toString(lines));
        }
    }

    private void writeLinesImpl(File file, String encoding, String ... lines) throws IOException {
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), encoding));
        try {
            for (String line : lines) {
                writer.write(line);
                writer.newLine();
            }
//            writer.flush(); // implicitly called at writer.close() invocation
        } finally {
            writer.close();
        }
    }


P.S. плюс, конечно, джавадок на методы.
http://denis-zhdanov.blogspot.com
Re[2]: Какие вы видите проблемы в данном коде?
От: . Великобритания  
Дата: 16.05.07 16:02
Оценка: 1 (1)
Дмитрий В wrote:

> if(fileWriter!=null)

Вот это лишнее, имхо.
Posted via RSDN NNTP Server 2.1 beta
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[3]: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 16.05.07 07:53
Оценка: +1
Здравствуйте, dshe, Вы писали:

D>Что касается 1 и 3. согласен. А вот 2 -- спорный пункт. Совершенно не факт, что в данном случае с IOException'ом нужно обязательно что-то сделать. Вполне возможно, что данный writeLines -- это не единственный утилитный метод, а есть еще readLines и еще некоторое количество подобных методов, которые используются совместно в неком методе performSomeHighLevelWork, который, кстати, может сам может использовать низкоуровневое Java IO API. Поэтому, вместо того, чтобы в каждом из методов типа writeLines писать

D>
D>        } catch (IOException e) {
D>            throw new IllegalStateException("Unexpected exception occured during blah-blah-blah", e);
D>        }
D>

D>может оказаться проще написать это один раз в performSomeHighLevelWork.

Это да, лень — одно из оснвных достоинств разрабочика. Понятно, что не бывает универсального решения, которое было бы лучшим во всех ситуациях. Мое предложение относится к 'standalone method'.


D>Ну и естественно, не забыть cause.


http://denis-zhdanov.blogspot.com
Re[5]: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 17.05.07 10:06
Оценка: +1
Здравствуйте, Donz, Вы писали:

D>А в чём проблема то? Там, наверху, в зависимости от того, что и куда пишем, сами разберутся, что с исключением делать.


В том, что неудобно. Там, наверху, должны сами решать, хотят они обрабатывать эксепшн или не хотят (мы со своей стороны четко прописываем IllegalStateException в сигнатуре, плюс пишем джавадок, т.е. даем всю необходимую информацию). В случае же с checked exception наверху должны всегда производить обработку.


D>По коду. Если возникло исключение во время работы методов write, то, возможно, будет исключение и при попытке закрыть поток, но так как закрытие находится в блоке finally, то исключение от попытки закрытия потока подавит "настоящее" исключение, то есть возможно потеряется истинная причина исключительной ситуации.


Да, теоретически возможно, но, имхо, в данном случае преимущество обработки такой ситуации меньше, чем увеличение объема и уменьшение читабельности кода, необходимого для этого.
http://denis-zhdanov.blogspot.com
Re[7]: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 17.05.07 11:36
Оценка: -1
Здравствуйте, Donz, Вы писали:

D>Подмена IOException на IllegalStateException, ИМХО, некорректна.


А логическое обоснование можно?


D>К тому же, хотя ты и написал ниже, что объявление метода через throws тоже не нравится, но меня такой вариант, если в данном месте я не хочу ничего обрабатывать, вполне устраивает.


Да ради Бога, я ж не настаиваю, на том, что мой подход самый правильный подход


D>>>По коду. Если возникло исключение во время работы методов write, то, возможно, будет исключение и при попытке закрыть поток, но так как закрытие находится в блоке finally, то исключение от попытки закрытия потока подавит "настоящее" исключение, то есть возможно потеряется истинная причина исключительной ситуации.


B>>Да, теоретически возможно, но, имхо, в данном случае преимущество обработки такой ситуации меньше, чем увеличение объема и уменьшение читабельности кода, необходимого для этого.

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

На самом деле, я сразу не сообразил, что ошибки-то в этом нет (в случае оборачивания в unchecked; как альтернатива можно использовать логирование). Кинуть эксепшн в обоих случаях (и при write(), и при close()) не получится ==> надо выбирать что-то одно. Я выбираю вариант, когда эксепшн из close() перезатирает эксепшн из write(). Эта ситуация мне не нравится меньше, чем когда наверх летит эксепшн от write(), и остается открытый поток.
http://denis-zhdanov.blogspot.com
Re[2]: Какие вы видите проблемы в данном коде?
От: Аноним  
Дата: 17.05.07 13:21
Оценка: +1
Здравствуйте, bolshik, Вы писали:

B>Здравствуйте, Foror, Вы писали:


<skip>

B>2. Я бы не кидал checked exception наружу, т.е. либо тупо логировать его, либо оборачивать в unchecked;

<skip>

Этот пункт меня убил
Re[14]: Какие вы видите проблемы в данном коде?
От: Donz Россия http://donz-ru.livejournal.com
Дата: 17.05.07 14:31
Оценка: +1
Здравствуйте, bolshik, Вы писали:

B>Я ж человек ленивый, предпочитаю использовать стандартное и готовое. Но! Есть вариант, поражающий своей точностью — заводим свой unchecked CantWriteToFileException, и кидаем его в этом случае. IOException просто отдыжает


Ну в общем, я предпочитаю кинутые VM исключения сохранять приблизительно такими, какие они есть, а не создавать исключение другого класса.
К тому же, ты сам сказал выше:

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

checked исключение в интерфейсе можно зафиксировать в отличие от unchecked. Уповать на хороший жавадок и то, что пользователь твоей библиотеки будет вдумчиво его читать, всё же не стоит.
Re[16]: Какие вы видите проблемы в данном коде?
От: Donz Россия http://donz-ru.livejournal.com
Дата: 18.05.07 09:24
Оценка: :)
Здравствуйте, bolshik, Вы писали:

B>Что значит '... в отличие от unchecked'? Кто-то запещает объявить в интерфейсе метод с деклацацией unchecked эксепшна во throws?

Ок, можно, но всё равно смысла нет Ни разу, кстати, не видел, чтобы кто-то объявлял unchecked исключения в интерфейсе

D>>Уповать на хороший жавадок и то, что пользователь твоей библиотеки будет вдумчиво его читать, всё же не стоит.


B>Равно как и на то, что пользователь не будет делать catch (Exception ignore) {}

В этом случае программист точно сознательно забьёт на обработку. А джавадок он может невнимательно прочитать и про объявление исключения в интерфейсе забыть.
В общем, каждый остался при своём мнении Предлагаю дискуссию закончить.
С пятницей
Какие вы видите проблемы в данном коде?
От: Foror http://foror.ru
Дата: 16.05.07 05:32
Оценка:
void writeLines(File file, String[] lines, String encoding) throws IOException {
    OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
    try {
        for (String line: lines) {
            os.write(line.getBytes(encoding));
            os.write('\n');
        }
    } finally {
        os.close();
    }
}
Re[2]: Какие вы видите проблемы в данном коде?
От: aefimov Россия
Дата: 16.05.07 06:05
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>
B>lineSeparator = java.lang.System.getProperty('line.separator');
B>


Согласен, весьма распространненная ошибка.
Вот даже при конфигурации log4j надо указывать не \n, а $n, иначе переводы строк будут не те и лог смотреть будет не приятно
Re[3]: Какие вы видите проблемы в данном коде?
От: b_manvelyan Украина  
Дата: 16.05.07 06:28
Оценка:
Здравствуйте, aefimov, Вы писали:

A>Вот даже при конфигурации log4j надо указывать не \n, а $n, иначе переводы строк будут не те и лог смотреть будет не приятно


Ой, а можно чуть подробнее, гед надо указывать. Спасибо.
Re[5]: Какие вы видите проблемы в данном коде?
От: b_manvelyan Украина  
Дата: 16.05.07 06:35
Оценка:
Здравствуйте, aefimov, Вы писали:

_>>Ой, а можно чуть подробнее, гед надо указывать. Спасибо.


A>Я чуток напутал — не $n, а %n:


Фух, а я ж испугался, что столько лет использую и не лучшим образом.
Re[3]: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 16.05.07 07:02
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Эй, а cause? Так по логам нельзя будет восстановить причину ошибки.


Да, про cause забыл
http://denis-zhdanov.blogspot.com
Re[2]: Какие вы видите проблемы в данном коде?
От: MAPCUAHUH  
Дата: 16.05.07 15:32
Оценка:
Здравствуйте, bolshik, Вы писали:

B>Здравствуйте, Foror, Вы писали:



B>

B>Итого:


B>
B>    public void writeLines(File file, String encoding, String ... lines) throws IllegalStateException {
B>        try {
B>            writeLinesImpl(file, encoding, lines);
B>        } catch (IOException e) {
B>            throw new IllegalStateException("Unexpected exception occured during writing to file. File: "
B>                    + file.getAbsolutePath() + ", data to write: " + Arrays.toString(lines));
B>        }
B>    }

B>    private void writeLinesImpl(File file, String encoding, String ... lines) throws IOException {
B>        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), encoding));
B>        try {
B>            for (String line : lines) {
B>                writer.write(line);
B>                writer.newLine();
B>            }
B>//            writer.flush(); // implicitly called at writer.close() invocation
B>        } finally {
B>            writer.close();
B>        }
B>    }
B>


Что-то не понял для чего так оборачивать метод writeLinesImpl и почему не кидать IOException наерх?
Re: Какие вы видите проблемы в данном коде?
От: Дмитрий В  
Дата: 16.05.07 15:49
Оценка:
А я б написал так:

public static void writeLines(File file, String[] lines) throws IOException {
        PrintStream fileWriter = new PrintStream(file);
        try {
            for (String line : lines) {
                fileWriter.println(line);
            }
        } finally {
            if(fileWriter!=null)
                fileWriter.close();
        }
    }
Re[3]: Какие вы видите проблемы в данном коде?
От: Дмитрий В  
Дата: 16.05.07 16:08
Оценка:
Здравствуйте, ., Вы писали:

.>Дмитрий В wrote:


>> if(fileWriter!=null)

.>Вот это лишнее, имхо.

Эт точно, надо было так написать


public static void writeLines(File file, String[] lines) throws IOException {
        PrintStream fileWriter = null;
        try {
           fileWriter = new PrintStream(file);
            for (String line : lines) {
                fileWriter.println(line);
            }
        } finally {
            if(fileWriter!=null)
                fileWriter.close();
        }
    }
Re[3]: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 17.05.07 07:00
Оценка:
Здравствуйте, MAPCUAHUH, Вы писали:

MAP>Что-то не понял для чего так оборачивать метод writeLinesImpl и почему не кидать IOException наерх?


Потому что IOException — checked exception.
http://denis-zhdanov.blogspot.com
Re[6]: Какие вы видите проблемы в данном коде?
От: aka50 Россия  
Дата: 17.05.07 10:10
Оценка:
Здравствуйте, bolshik, Вы писали:

B>Здравствуйте, Donz, Вы писали:


D>>А в чём проблема то? Там, наверху, в зависимости от того, что и куда пишем, сами разберутся, что с исключением делать.


B>В том, что неудобно. Там, наверху, должны сами решать, хотят они обрабатывать эксепшн или не хотят (мы со своей стороны четко прописываем IllegalStateException в сигнатуре, плюс пишем джавадок, т.е. даем всю необходимую информацию). В случае же с checked exception наверху должны всегда производить обработку.


А что мешает им кинуть выше? Ведь checked на то и checked чтобы обратить внимание на то, что метод не может принять решение что делать дальше. Т.е. сами по себе checked конечно не панацея, но отказываться от них полностью — суть зло.

Я обычно руководствуюсь простыми правилами:
1. Утилитный класс или внутренняя логика — checked
2. Компонентный (например dao) — unchecked либо один большой checked
Re[7]: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 17.05.07 10:41
Оценка:
Здравствуйте, aka50, Вы писали:

A>А что мешает им кинуть выше?


Под 'наверху должны всегда производить обработку' я имел ввиду как оборачивание в try-catch, так и объявление во throws.


A>Ведь checked на то и checked чтобы обратить внимание на то, что метод не может принять решение что делать дальше.


Имхо ситауция, когда метод кидает unchecked, не означает, что метод принял решение, что делать дальше


A>Т.е. сами по себе checked конечно не панацея, но отказываться от них полностью — суть зло.


Видишь, здесь разные подходы — мне кажется, что пользователю моего класса удобнее работать, не будучи обязанным ловить какие бы то ни было эксепшны. Но при этом вся информация по поводу того, что может вылететь и в каких случаях, должна быть доступна (равно как и cause ). И на текущем этапе моей девелоперской жизни я вижу только минусы checked exceptions перед unchecked.


A>Я обычно руководствуюсь простыми правилами:

A>1. Утилитный класс или внутренняя логика — checked
A>2. Компонентный (например dao) — unchecked либо один большой checked

Ок.
http://denis-zhdanov.blogspot.com
Re[6]: Какие вы видите проблемы в данном коде?
От: Donz Россия http://donz-ru.livejournal.com
Дата: 17.05.07 11:18
Оценка:
Здравствуйте, bolshik, Вы писали:

D>>А в чём проблема то? Там, наверху, в зависимости от того, что и куда пишем, сами разберутся, что с исключением делать.


B>В том, что неудобно. Там, наверху, должны сами решать, хотят они обрабатывать эксепшн или не хотят (мы со своей стороны четко прописываем IllegalStateException в сигнатуре, плюс пишем джавадок, т.е. даем всю необходимую информацию). В случае же с checked exception наверху должны всегда производить обработку.

Подмена IOException на IllegalStateException, ИМХО, некорректна. К тому же, хотя ты и написал ниже, что объявление метода через throws тоже не нравится, но меня такой вариант, если в данном месте я не хочу ничего обрабатывать, вполне устраивает.

D>>По коду. Если возникло исключение во время работы методов write, то, возможно, будет исключение и при попытке закрыть поток, но так как закрытие находится в блоке finally, то исключение от попытки закрытия потока подавит "настоящее" исключение, то есть возможно потеряется истинная причина исключительной ситуации.


B>Да, теоретически возможно, но, имхо, в данном случае преимущество обработки такой ситуации меньше, чем увеличение объема и уменьшение читабельности кода, необходимого для этого.

Думаю, это зависит от критичности приложения и необходимого уровня информативности возможных исключений.
Re[8]: Какие вы видите проблемы в данном коде?
От: aka50 Россия  
Дата: 17.05.07 11:24
Оценка:
Здравствуйте, bolshik, Вы писали:

B>Здравствуйте, aka50, Вы писали:


A>>Т.е. сами по себе checked конечно не панацея, но отказываться от них полностью — суть зло.


B>Видишь, здесь разные подходы — мне кажется, что пользователю моего класса удобнее работать, не будучи обязанным ловить какие бы то ни было эксепшны. Но при этом вся информация по поводу того, что может вылететь и в каких случаях, должна быть доступна (равно как и cause ). И на текущем этапе моей девелоперской жизни я вижу только минусы checked exceptions перед unchecked.


Дело в том, что checked обязывает перехватывать исключение, что дает определенную гарантию _осмысленной обработки_. Не зря в Runnable нету throws Exception, а в Callable есть, т.к. в случае с Callable эти ексепшины будут гарантированно будут обработаны Executor-ом а далее пользователем в методе Future#get. По этому unchecked — это для случаев неустранимых ошибок (например падение dao уровня), что согласись в случае с чтением из файла таковым не является. Принять решение "шеф все пропало" может только код выше, который знает, что за файл он читает (конфиг и тогда RuntimeException("Пепец, нету конфига")) или my.doc и тогда красивое окошечко "не хотите ли более правильно файлик показать"...

Так вот представь, что последовательность вызовов module1 -> module2 -> module3 при чем module1 — это компонентный класс. Таким образом если везде используются checked всю обработку ошибок можно сконцентрировать в module1. В случае uncheked в module1 придется обороачивать это все try { } catch (Excetpion e) throw new Module1Exception(e) и не будет ни каких шансов обработать ситуацию (т.к. module3 может бросить что угодно, не будешь же весь call graph на предмет javadoc-ов просмтаривать).
Re[9]: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 17.05.07 11:37
Оценка:
Здравствуйте, LeonidV, Вы писали:

LV>Не согласен. Зачастую уровень, который кидает исключение, сам не может с ним справится. Самый простой и наглядный пример — открытие файла, спрятанное в вызовах и затребованное пользователем. Тут логично вынести обработку исключения поближе к пользователю.


Дык пусть обрабатывает unchecked, кто ж ему мешает-то?
http://denis-zhdanov.blogspot.com
Re[9]: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 17.05.07 11:56
Оценка:
Здравствуйте, aka50, Вы писали:

A>Дело в том, что checked обязывает перехватывать исключение, что дает определенную гарантию _осмысленной обработки_.


Я бы сказал, что так задумывалось, но на деле мы зачастую видим catch (IOException ignore) {}.


A>Не зря в Runnable нету throws Exception, а в Callable есть, т.к. в случае с Callable эти ексепшины будут гарантированно будут обработаны Executor-ом а далее пользователем в методе Future#get.


А что, если бы в сигнатуре не было бы объявления throws Exception, в Executor'е нельзя было бы делать catch (Exception)?


A>По этому unchecked — это для случаев неустранимых ошибок (например падение dao уровня), ...


Очень спорное утверждение. По такой логике получается, что спринговский DataAccessException — вполне себе устранимый эксепшн, а какой-нить java.sql.Statement.execute() неустранимый?


A>...что согласись в случае с чтением из файла таковым не является.


Во-первых, запись, во-торых не соглашусь — все зависит от задачи


A>Принять решение "шеф все пропало" может только код выше, который знает, что за файл он читает (конфиг и тогда RuntimeException("Пепец, нету конфига")) или my.doc и тогда красивое окошечко "не хотите ли более правильно файлик показать"...


Так пусть же он принимает это решение на основании анализа checked exception'a.


A>Так вот представь, что последовательность вызовов module1 -> module2 -> module3 при чем module1 — это компонентный класс. Таким образом если везде используются checked всю обработку ошибок можно сконцентрировать в module1. В случае uncheked в module1 придется обороачивать это все try { } catch (Excetpion e) throw new Module1Exception(e)...


Вот как-то не дается мне глубина этой логики. Что есть такого у checked, что позволяет 'всю обработку ошибок сконцентрировать', а в случае unchecked 'придется обороачивать это все try { } catch (Excetpion e) throw new Module1Exception(e)'...


A>...и не будет ни каких шансов обработать ситуацию (т.к. module3 может бросить что угодно, не будешь же весь call graph на предмет javadoc-ов просмтаривать).


Module3 дурак что ли бросать все, что угодно? Все модули общаются через строго определенный надор интерфейсов, в которых зафиксированы эксепшны, которые могут методы и указано, в каких случаях это происходит, т.е. мы можем понять, когда стоит их ловить и обрабатывать...
http://denis-zhdanov.blogspot.com
Re[10]: Какие вы видите проблемы в данном коде?
От: aka50 Россия  
Дата: 17.05.07 12:29
Оценка:
Здравствуйте, bolshik, Вы писали:

B>Здравствуйте, aka50, Вы писали:


A>>Дело в том, что checked обязывает перехватывать исключение, что дает определенную гарантию _осмысленной обработки_.

B>Я бы сказал, что так задумывалось, но на деле мы зачастую видим catch (IOException ignore) {}.
Проблемы трудностей выстрела в свою ногу — проблемы практикующих такие выстрелы.

A>>Не зря в Runnable нету throws Exception, а в Callable есть, т.к. в случае с Callable эти ексепшины будут гарантированно будут обработаны Executor-ом а далее пользователем в методе Future#get.

B>А что, если бы в сигнатуре не было бы объявления throws Exception, в Executor'е нельзя было бы делать catch (Exception)?
В случае с Runnable видно: выше никого нет (разве что Thread.UncaughtExceptionHandler), а в случае с Callable интерфейс явно говорит, что ошибка будет обработана (хотя бы в виде ExecutionExeception).

A>>По этому unchecked — это для случаев неустранимых ошибок (например падение dao уровня), ...

B>Очень спорное утверждение. По такой логике получается, что спринговский DataAccessException — вполне себе устранимый эксепшн, а какой-нить java.sql.Statement.execute() неустранимый?
Я, если честно, не в восторге от подхода spring-а к тотальному отказу от checked. Но с другой стороны spring обычно используется для объединения компонент. В этом случае компонент обязан сам разбираться с проблемами и бросать unchecked и узкий набор checked только в крайнем случае, т.к. во многих программах забытый unchecked скорее всtго пришибет весь поток и хорошо если это будет не main поток.

A>>Принять решение "шеф все пропало" может только код выше, который знает, что за файл он читает (конфиг и тогда RuntimeException("Пепец, нету конфига")) или my.doc и тогда красивое окошечко "не хотите ли более правильно файлик показать"...

B>Так пусть же он принимает это решение на основании анализа checked exception'a.
Кто? Если writeData кинет unchecked кто будет принимать решение? Или это должен делать сам writeData. А если у нас несколько writeData, которые еще и не так просто в один загнать? Если у нас writeData зарыт в другом классе и к writeData у нас нет javadoc (если обязывать это все вести в javadoc — получим проблему с актуальностью). Тогда вопрос, почему бы не использовать возможности компилятора?

A>>Так вот представь, что последовательность вызовов module1 -> module2 -> module3 при чем module1 — это компонентный класс. Таким образом если везде используются checked всю обработку ошибок можно сконцентрировать в module1. В случае uncheked в module1 придется обороачивать это все try { } catch (Excetpion e) throw new Module1Exception(e)...

B>Вот как-то не дается мне глубина этой логики. Что есть такого у checked, что позволяет 'всю обработку ошибок сконцентрировать', а в случае unchecked 'придется обороачивать это все try { } catch (Excetpion e) throw new Module1Exception(e)'...
То, что все внутренние методы будут промаркированны соответствующими ексепшонами (возможно даже иерархией, типа ProtoException <- ProtoValidationExecetpion <- ProtoMissingFieldException). В случае unckecked я должен буду проанализировать весь call graph чтобы этот ProtoMissingField аж до самого main не вылетел, когда просто забылил или не знали что такое может выскочить.

A>>...и не будет ни каких шансов обработать ситуацию (т.к. module3 может бросить что угодно, не будешь же весь call graph на предмет javadoc-ов просмтаривать).

B>Module3 дурак что ли бросать все, что угодно? Все модули общаются через строго определенный надор интерфейсов, в которых зафиксированы эксепшны, которые могут методы и указано, в каких случаях это происходит, т.е. мы можем понять, когда стоит их ловить и обрабатывать...
Так и я о том же, но котролировать внутри модуля проще именно checked, т.е. все методы внутри модуля кидаются разнымими внутримодульными ексепшонами... Наверх вылетают либо "страшные" ConcurrentModification-ы которые однозначно показывают — мега проблема либо небольшой набор checked (в случае с spring они unchecked, но пользоваться unchked особо не заставляют).

Вот посуди сам, разработчик забыл перехватить IO при попытки записи в кеш неких данных, и из вызова module1.findData вылетело Module1(IOException("Can't write /tmp/2342SSDGF.dat")) О чем это скажет тому, кто пользуется module1 и может даже не подозревать что там вообще файлы используются? Правильнее будет Mudule1CacheOperationFailed("Can't write to cache file", IOExce(...)), но для того, чтобы проконтролировать все это легче использовать checked.
Re[8]: Какие вы видите проблемы в данном коде?
От: Blazkowicz Россия  
Дата: 17.05.07 12:30
Оценка:
Здравствуйте, bolshik, Вы писали:


D>>Подмена IOException на IllegalStateException, ИМХО, некорректна.

B>А логическое обоснование можно?

Оно в API доке к классу IllegalStateException.
Re[10]: Какие вы видите проблемы в данном коде?
От: aka50 Россия  
Дата: 17.05.07 12:31
Оценка:
Здравствуйте, bolshik, Вы писали:

B>Здравствуйте, aka50, Вы писали:


A>>Дело в том, что checked обязывает перехватывать исключение, что дает определенную гарантию _осмысленной обработки_.

B>Я бы сказал, что так задумывалось, но на деле мы зачастую видим catch (IOException ignore) {}.

А вообще какой-то спор не правильный... в инете полно флейма на эту тему... т.е. нужно смотреть конкретную задачу и условия, в которых пишется приложение... Архитектуру... в общем использовать или не использовать checked — "it depends".
Re[9]: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 17.05.07 12:34
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Здравствуйте, bolshik, Вы писали:



D>>>Подмена IOException на IllegalStateException, ИМХО, некорректна.

B>>А логическое обоснование можно?

B>Оно в API доке к классу IllegalStateException.


Signals that a method has been invoked at an illegal or inappropriate time. In other words, the Java environment or Java application is not in an appropriate state for the requested operation.


Нет у процесса сейчас права на запись в файл — чем не 'illegal or inappropriate time'?
http://denis-zhdanov.blogspot.com
Re[10]: Какие вы видите проблемы в данном коде?
От: Blazkowicz Россия  
Дата: 17.05.07 12:36
Оценка:
Здравствуйте, bolshik, Вы писали:

B>

B>Signals that a method has been invoked at an illegal or inappropriate time. In other words, the Java environment or Java application is not in an appropriate state for the requested operation.


B>Нет у процесса сейчас права на запись в файл — чем не 'illegal or inappropriate time'?


Состояние внешней среды не является состоянием "Java environment or Java application"
Re[11]: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 17.05.07 12:52
Оценка:
Здравствуйте, aka50, Вы писали:

A>Проблемы трудностей выстрела в свою ногу — проблемы практикующих такие выстрелы.


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


A>В случае с Runnable видно: выше никого нет (разве что Thread.UncaughtExceptionHandler), а в случае с Callable интерфейс явно говорит, что ошибка будет обработана (хотя бы в виде ExecutionExeception).


Имхо то, что у call стоит throws Exception значит не то, что 'ошибка будет обработана', а то, что код, работающий с этим интерфейсом, должен писать обработчик Exception.


A>Я, если честно, не в восторге от подхода spring-а к тотальному отказу от checked. Но с другой стороны spring обычно используется для объединения компонент.


Ну, скажем, DataAccessException используется для объединения с субд.


A>В этом случае компонент обязан сам разбираться с проблемами и бросать unchecked и узкий набор checked только в крайнем случае, т.к. во многих программах забытый unchecked скорее всtго пришибет весь поток и хорошо если это будет не main поток.



A>Кто? Если writeData кинет unchecked кто будет принимать решение? Или это должен делать сам writeData. А если у нас несколько writeData, которые еще и не так просто в один загнать?


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


A>Если у нас writeData зарыт в другом классе и к writeData у нас нет javadoc (если обязывать это все вести в javadoc — получим проблему с актуальностью). Тогда вопрос, почему бы не использовать возможности компилятора?


По такой логике джавадок вообще вредная вещь, потому что порождает проблемы с актуальностью?


A>То, что все внутренние методы будут промаркированны соответствующими ексепшонами (возможно даже иерархией, типа ProtoException <- ProtoValidationExecetpion <- ProtoMissingFieldException). В случае unckecked я должен буду проанализировать весь call graph чтобы этот ProtoMissingField аж до самого main не вылетел, когда просто забылил или не знали что такое может выскочить.


А кто мешает сделать ProtoException <- ProtoValidationExecetpion <- ProtoMissingFieldException unchecked а анализировать их только тогда, когда это действительно нужно?


A>Так и я о том же, но котролировать внутри модуля проще именно checked, т.е. все методы внутри модуля кидаются разнымими внутримодульными ексепшонами... Наверх вылетают либо "страшные" ConcurrentModification-ы которые однозначно показывают — мега проблема либо небольшой набор checked (в случае с spring они unchecked, но пользоваться unchked особо не заставляют).


A>Вот посуди сам, разработчик забыл перехватить IO при попытки записи в кеш неких данных, и из вызова module1.findData вылетело Module1(IOException("Can't write /tmp/2342SSDGF.dat")) О чем это скажет тому, кто пользуется module1 и может даже не подозревать что там вообще файлы используются? Правильнее будет Mudule1CacheOperationFailed("Can't write to cache file", IOExce(...)), но для того, чтобы проконтролировать все это легче использовать checked.


По-моему, это другая сторона той же медали, что и catch (Exception) {}. Нормальный чувак не будет писать catch (Exception) {}, и не будет же игнорировать unchecked эксепшны, объявленные во throws, а с unchecked геморроя меньше.
http://denis-zhdanov.blogspot.com
Re[11]: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 17.05.07 12:52
Оценка:
Здравствуйте, aka50, Вы писали:

A>А вообще какой-то спор не правильный... в инете полно флейма на эту тему... т.е. нужно смотреть конкретную задачу и условия, в которых пишется приложение... Архитектуру... в общем использовать или не использовать checked — "it depends".


http://denis-zhdanov.blogspot.com
Re[11]: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 17.05.07 12:59
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Состояние внешней среды не является состоянием "Java environment or Java application"


Почему же, можно трактовать так, что запущено джава-приложение, у которого нет прав на запись в файл, т.е. 'Java application is not in an appropriate state for the requested operation'.
http://denis-zhdanov.blogspot.com
Re[12]: Какие вы видите проблемы в данном коде?
От: Donz Россия http://donz-ru.livejournal.com
Дата: 17.05.07 13:23
Оценка:
Здравствуйте, bolshik, Вы писали:

B>>Состояние внешней среды не является состоянием "Java environment or Java application"


B>Почему же, можно трактовать так, что запущено джава-приложение, у которого нет прав на запись в файл, т.е. 'Java application is not in an appropriate state for the requested operation'.


Тогда таким образом можно трактовать любое исключение. Ну не вовремя ява-машина запустилась: сервер сгорел или у пользователя настроение плохое
IOException — даже само название класса исключения говорит о том, что произошла ошибка ввода/вывода, то есть надо смотреть в сторону работы с потоками.
IllegalStateException — ява-машина не готова запустить какой-либо метод или выполнить операцию из-за состояния самой ява-машины, а не внешнего состояния, как это уже сказал Blazkowicz
Re[9]: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 17.05.07 13:27
Оценка:
Здравствуйте, Donz, Вы писали:

D>Ты же поток не закроешь, если кинешь исключение о том, что не получилось его закрыть.

D>Если код, например, построить таким образом:
D>
D>OutputStream out = new smth.getOutputStream();
D>try
D>{
D>  out.write( data );
D>}
D>finally
D>{
D>  try
D>  {
D>    out.close();
D>  }
D>  catch( Exception ignored ){}
D>}
D>

D>То будет выполнена попытка закрытия поток, и наверху мы получим "правильное исключение".
D>Ещё можно ввести флажок, а каким образом вызван блок finally: нормально или из-за исключения, и, анализируя флажок, принимать решение, подавлять исключение, возникшее при закрытии потока, или выбрасывать его наверх. Только это уже как-то мудрено получается. Я обычно использую приведёный код.

Да, правильно, я протупил, так все хорошо будет.
Единственно что, это как раз пример увеличения объема кода и уменьшения читабельности.
http://denis-zhdanov.blogspot.com
Re[3]: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 17.05.07 13:27
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Этот пункт меня убил


Покойся с миром..
http://denis-zhdanov.blogspot.com
Re[13]: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 17.05.07 13:31
Оценка:
Здравствуйте, Donz, Вы писали:

D>Тогда таким образом можно трактовать любое исключение. Ну не вовремя ява-машина запустилась: сервер сгорел или у пользователя настроение плохое

D>IOException — даже само название класса исключения говорит о том, что произошла ошибка ввода/вывода, то есть надо смотреть в сторону работы с потоками.
D>IllegalStateException — ява-машина не готова запустить какой-либо метод или выполнить операцию из-за состояния самой ява-машины, а не внешнего состояния, как это уже сказал Blazkowicz

Да, ок, согласен, что IOException точнее указывает на то, что произошла ошибка i/o, чем ISE.
Я ж человек ленивый, предпочитаю использовать стандартное и готовое. Но! Есть вариант, поражающий своей точностью — заводим свой unchecked CantWriteToFileException, и кидаем его в этом случае. IOException просто отдыжает
http://denis-zhdanov.blogspot.com
Re[12]: Какие вы видите проблемы в данном коде?
От: aka50 Россия  
Дата: 17.05.07 13:56
Оценка:
Здравствуйте, bolshik, Вы писали:

B>Здравствуйте, aka50, Вы писали:



A>>В случае с Runnable видно: выше никого нет (разве что Thread.UncaughtExceptionHandler), а в случае с Callable интерфейс явно говорит, что ошибка будет обработана (хотя бы в виде ExecutionExeception).


B>Имхо то, что у call стоит throws Exception значит не то, что 'ошибка будет обработана', а то, что код, работающий с этим интерфейсом, должен писать обработчик Exception.

Что в общем-то одно и то же — принуждение к обработке. try { } catch( Exception ignore) {} — это тоже своего рода обработка.

A>>Я, если честно, не в восторге от подхода spring-а к тотальному отказу от checked. Но с другой стороны spring обычно используется для объединения компонент.

B>Ну, скажем, DataAccessException используется для объединения с субд.
Это и есть иллюстрация подхода "it depends" и правила "unchecked — это критическое событие". Т.к. доступ к бд — это отдельный модуль (который еще может помимо прочего еще и прозрачно ексепшины преобразовывать). При этом DataAccessException вполне сочетается с критическим событием и как минимум сессию в web приложении полюбому грохать... При этом при ошибке sql no records found, лучше наверное возвращать пустой список или null, чем швыряться unchecked. В случае с writeFile решение о том, фатально это или нет должен принять внешний код, и чтобы не было у него сурпризов в виде uchecked их лучше сделать checked.
B>По такой логике джавадок вообще вредная вещь, потому что порождает проблемы с актуальностью?
Да, т.к. это примерно то же самое, что сделать все методы Object, а уже внутри проверять. Реальные типы описывать в javadoc. Зато пользователю будет удобно можно пихать в метод что угодно...

К стати, как вариант можно делать два метода, writeAndForget() и writeData() throws IOException
Re[13]: Какие вы видите проблемы в данном коде?
От: aka50 Россия  
Дата: 17.05.07 13:58
Оценка:
Здравствуйте, aka50, Вы писали:

A>Да, т.к. это примерно то же самое, что сделать все методы Object, а уже внутри проверять. Реальные типы описывать в javadoc. Зато пользователю будет удобно можно пихать в метод что угодно...


Имел ввиду параметры методов типа doIt(Object param1, Object param2)
Re[13]: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 17.05.07 15:19
Оценка:
Здравствуйте, aka50, Вы писали:

A>...


Поскольку имхо мы уже чутка зацикливаемся, официально заявляю, что твоя точка зрения мне понятна
Не могу с уверенностью сказать, что понятно объяснил свою
Подход к использованию checked/unchecked, при котором checked не используются, а unchecked корректно описываются в контракте метода, мне нравится больше.
Засим предлагаю завершить
http://denis-zhdanov.blogspot.com
Re[15]: Какие вы видите проблемы в данном коде?
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 17.05.07 15:23
Оценка:
Здравствуйте, Donz, Вы писали:

D>Ну в общем, я предпочитаю кинутые VM исключения сохранять приблизительно такими, какие они есть, а не создавать исключение другого класса.


Это здорово, вот если бы только исключения VM были unchecked...


D>К тому же, ты сам сказал выше:


D>

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

D>checked исключение в интерфейсе можно зафиксировать в отличие от unchecked.

Что значит '... в отличие от unchecked'? Кто-то запещает объявить в интерфейсе метод с деклацацией unchecked эксепшна во throws?


D>Уповать на хороший жавадок и то, что пользователь твоей библиотеки будет вдумчиво его читать, всё же не стоит.


Равно как и на то, что пользователь не будет делать catch (Exception ignore) {}
http://denis-zhdanov.blogspot.com
Re[14]: Какие вы видите проблемы в данном коде?
От: aka50 Россия  
Дата: 17.05.07 16:47
Оценка:
Здравствуйте, bolshik, Вы писали:

B>Засим предлагаю завершить

Re[2]: Какие вы видите проблемы в данном коде?
От: Дмитрий В  
Дата: 21.05.07 12:18
Оценка:
Здравствуйте, ddocker, Вы писали:

D>аяй-яй, что же вы так тестовые задания всем интернетом решаете: http://company.yandex.ru/inside/job/dev_bugtracker.xml

Бгыгыгыгыгыыыыыыыыыыыы
А там еще задания остались!
Re[2]: Какие вы видите проблемы в данном коде?
От: Donz Россия http://donz-ru.livejournal.com
Дата: 21.05.07 14:13
Оценка:
Здравствуйте, ddocker, Вы писали:

D>аяй-яй, что же вы так тестовые задания всем интернетом решаете: http://company.yandex.ru/inside/job/dev_bugtracker.xml

Интересно, что скажут по этому обсуждению экзаменаторы из Яндекса
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.