Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2006.04.16;
Скачать: [xml.tar.bz2];

Вниз

Прослушал тут курсы C#...   Найти похожие ветки 

 
iZEN ©   (2006-03-21 21:32) [80]

Все классы-наследники java.lang.RuntimeException, таким образом, являются полными аналогами Exception в Delphi и C#.


 
iZEN ©   (2006-03-21 21:34) [81]

>Petr V. Abramov ©   (21.03.06 21:10) [77]
>> Игорь Шевченко ©   (21.03.06 21:05) [76]
>> В .Net код очень даже может выбросить Exception, которого совсем не ждешь.
>Я так понял, что если какая-то неожиданная (даже самим автором метода) фигня вылезет, но она не указана в throws, то все пойдет, как в старом добром Delphi32

Совершенно верно.
С системными ошибками времени выполнения похожая ситация.


 
wicked ©   (2006-03-21 21:36) [82]


> По-моему, программисты с ума бы сошли, если бы все исключения
> были бы проверяемыми. Представьте: в каждом методе писать
> список throws и/или вручную следить за целостностью ссылок
> (!= null), за ошибками выхода за границы массива, за ошибки
> приведения к типу (dynamic class casting), за переполнением
> при делении на ноль и т.д. Физически нецелесообразно объявлять
> все исключения проверяемыми. Да это и не нужно, если не
> надо расставлять акценты для защиты кода.

почти так сделано в Oberon - там исключений нету как класса, а то, что их заменяет, "ловушки", в коде просто так не перехватить....... это, конечно, AFAIK, поскольку близко с Обероном не работал.....


 
iZEN ©   (2006-03-21 21:37) [83]

Семантики использования throws <список_бросаемых_исключений> не существует ни в C#, ни в Delphi. Поэтому приходится использовать другие сигнальные механизмы. И только на стадии выполнения, к сожалению.


 
Игорь Шевченко ©   (2006-03-21 21:44) [84]

Petr V. Abramov ©   (21.03.06 21:10) [77]


>  Я так понял, что если какая-то неожиданная (даже самим
> автором метода) фигня вылезет, но она не указана в throws,
>  то все пойдет, как в старом добром Delphi32


Я с Java не знаком, поэтому не могу сказать. В .Net все пойдет также, как в старом добром Delphi - вылезет окошко, что программа совершила ужасное преступление и волей всех народов будет изнана с просторов оперативной памяти и на пять лет поражена в правах находиться в списке процессов.

iZEN ©   (21.03.06 21:25) [79]


> Физически нецелесообразно объявлять все исключения проверяемыми.


А нафига тогда проверяемые объявлять ? Все-таки, я присоединяюсь к просьбе Димы Акуличева и прошу привести пример, когда без проверямых исключений ни в какую не обойтись. Или ткнуть меня носом в номер поста, где такой пример уже приведен.


 
iZEN ©   (2006-03-21 22:20) [85]

>pasha_golub ©   (21.03.06 18:48) [73]
>> То есть, каждый метод, кроме a + b должен в заголовке писать
>> Throws EAccessViolation или как там он в Java называется ? :)
>Гыгы. Блин. По хорошему можно сразу весь список доступных эксепшнов.

>Lamer@fools.ua ©   (21.03.06 18:57) [74]
>>Игорь Шевченко ©   (21.03.06 18:28) [71]
>>То есть, каждый метод, кроме a + b должен в заголовке писать Throws EAccessViolation или как там он в Java называется ? :)
>Я совсем не спец по Java, но поскольку он весьма похож на .NET, рискну предположить, что как и в .NET, пользовательский код не может бросить исключения типа AccessViolationException. Правда, в .net (точнее в c#) есть unsafe код. В нём такое исключение может произойти.

Ладно, напишу что можно делать с исключениями в Java, но тогда пусть кто-то другой сделает аналогичные примеры на C#.
Итак, когда можно бросить и никогда не поймать ошибку системы времени выполнения:
public class ZerroDivide extends java.lang.Error {}

public class ArithmeticTest {
   public static int MyCrazzyMethod(int a, int b) throws ZerroDivide {
       try {
           return a / b;
       } catch (ArithmeticException ex) {
           throw new ZerroDivide();
       }
   }
   public static void main(String[] args) {
       ArithmeticTest.MyCrazzyMethod(10, 0);
   }
}

Вывод в консоли:
ZerroDivide
at ArithmeticTest.MyCrazzyMethod(ArithmeticTest.java:6)
at ArithmeticTest.main(ArithmeticTest.java:10)
Exception in thread "main"
Программа принудительно завершена с сообщением об ошибке.
Диалог системного сообщения: "Fatal exception occured. Program will exit." [OK]

Непроверяемые исключения:
public class ZerroDivide extends java.lang.RuntimeException {}

public class ArithmeticTest {
   public static int MyCrazzyMethod(int a, int b)  { /* писать в сигнатуре метода throws ZerroDivide необязательно - и так работает */
       try {
           return a / b;
       } catch (ArithmeticException ex) {
           throw new ZerroDivide();
       }
   }
   public static void main(String[] args) {
       ArithmeticTest.MyCrazzyMethod(10, 0);
   }
}

Вывод в консоли:
ZerroDivide
at ArithmeticTest.MyCrazzyMethod(ArithmeticTest.java:6)
at ArithmeticTest.main(ArithmeticTest.java:10)
Exception in thread "main"
Программа принудительно завершена с сообщением об ошибке.
Диалог системного сообщения: "Fatal exception occured. Program will exit." [OK]

Проверяемое исключение:
public class ZerroDivide extends java.lang.Exception {}

public class ArithmeticTest {
   public static int MyCrazzyMethod(int a, int b) throws ZerroDivide {
       try {
           return a / b;
       } catch (ArithmeticException ex) {
           throw new ZerroDivide();
       }
   }
   public static void main(String[] args) {
       /* Компилятор потребовал наличия конструкции try/catch или декларации throws в сигнатуре метода main. Сделал try/catch. */
       try {
           ArithmeticTest.MyCrazzyMethod(10, 0);
       } catch (ZerroDivide e) {
           e.printStackTrace();
       }
   }
}

Вывод в консоли:

ZerroDivide
at ArithmeticTest.MyCrazzyMethod(ArithmeticTest.java:6)
at ArithmeticTest.main(ArithmeticTest.java:12)
Объект исключения e вывел трассу вызовов методов в стэке, похожую на предыдущие случаи. И программа спокойно завершилась, так как ей выполнять больше нечего (в двух предыдущих случаях программа завершилась в досрочно-принудительном порядке).

Вот, в общем-то, иллюстративный материал.


 
Petr V. Abramov ©   (2006-03-21 22:35) [86]

> Игорь Шевченко ©   (21.03.06 21:44) [84]
> Я с Java не знаком, поэтому не могу сказать.
 Взаимно. Сужу по постам знакомых :))
> В .Net все пойдет также, как в старом добром Delphi
 С .нет также не знаком, верю на слово
> - вылезет окошко, что программа совершила ужасное преступление и
> волей всех народов будет изнана с просторов оперативной памяти и на
> пять лет поражена в правах находиться в списке процессов.
 где-то помнится видел... :))
 С кем не бывало...

 Ну и что? К раз-кому AV отношения не имеет.
Ну придумали идею < не буду повторять посты любиетелй жаба> Идея имеет право на жизнь. Ну не повторили ее в тчкНет. И что?


 
iZEN ©   (2006-03-21 22:38) [87]

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

java.lang.Error относится к непрверяемым исключениям (Unchecked Exceptions). То есть семантика обработки почти такая же, как и у java.lang.RuntimeException и, по аналогии, как у Delphi и C#.

Но важный момент: потомки java.lang.Error могут возникнуть самопроизвольно в прикладном коде, если виртуальная машина испытывает серьёзные проблемы в работе. Перехватить их можно в блоке catch (Error e) {...} или catch (Throwable e) {...}, но, как правило, это уже не имеет большого смысла для корректного завершения работы.


 
Игорь Шевченко ©   (2006-03-21 22:46) [88]

iZEN ©   (21.03.06 22:38) [87]

И все-таки, народу непонятно, зачем нужны checked exceptions...


 
Lamer@fools.ua ©   (2006-03-21 22:52) [89]

>>Игорь Шевченко ©   (21.03.06 21:05) [76]

>В .Net код очень даже может выбросить Exception, которого совсем не ждешь.

Естественно. Out of memory, Stack overflow и др. никто не отменял. Я конкретно о AccessViolationException написал. Слово "типа", в общем-то, было лишнее.

P.S.
По большому счёту, NullReferenceException — это реакция на спровоцированный Access Violation. Я смотрел, как это реализовывается. После получения адреса объекта, скажем, в регистр ECX перед обращением к члену класса исполняется следующий код:
cmp         dword ptr [ecx], ecx
В случае managed safe code в ECX может содержаться только одно из двух: либо нуль либо указатель на существующий объект.
Если в ECX нуль, то очевидно, что при исполнении вышеприведенного кода возникнет исключительная ситуация, которая неким образом обработается и сгенерируется NullReferenceException.

P.P.S.
Реальный AccessViolationException я наблюдал всего однажды, когда NOD32 не подружился с фреймворком 2.0. После чего NOD32 пришлось снести.


 
Petr V. Abramov ©   (2006-03-21 22:52) [90]

А как б... женатому человеку - вроде не нужны, но если уж есть, то можно и  попользоваться  Ж)))


 
Игорь Шевченко ©   (2006-03-21 23:47) [91]

Lamer@fools.ua ©   (21.03.06 22:52) [89]


> Я конкретно о AccessViolationException написал


Как уже было сказано одним из предыдущих ораторов, внутри unsafe-кода оно вроде может возникнуть. У меня такой вопрос, если я вызываю неую сборку, о деталях устройства которой не знаю, а она, вдруг возьми и работай с unsafe-кодом, например, вызывая какие-то старенькие библиотеки, и если в момент вызова внутри кода возник AccessViolation, то передастся ли он наверх, при условии, что сборка сама его не обрабатывает ?


 
Lamer@fools.ua ©   (2006-03-22 09:00) [92]

>>Игорь Шевченко ©   (21.03.06 23:47) [91]

>Как уже было сказано одним из предыдущих ораторов, внутри unsafe-кода оно вроде может возникнуть.
По-моему мной же =)

У меня такой вопрос, если я вызываю неую сборку, о деталях устройства которой не знаю, а она, вдруг возьми и работай с unsafe-кодом, например, вызывая какие-то старенькие библиотеки, и если в момент вызова внутри кода возник AccessViolation, то передастся ли он наверх, при условии, что сборка сама его не обрабатывает ?
Меня так и подмывает ответить одной из Ваших любимых фраз: практика — критерий истины :-)
Но вообще ответ — да.

P.S.
Только одно замечание. Unsafe код — это не работа с не .Net библиотеками. Это специальный механизЬм в .Net (точнее даже в C#). Работа с COM/OLE и обычными (не .Net) библиотеками осуществляется посредством механизма, именуемого Interop (interoperability).


 
FastReporter   (2006-03-22 10:40) [93]

KSergey ©   (21.03.06 18:01) [64]

Теперь получается так: я должен оббежать все 10 методов - и выяснить: а какого же они могут выкинуть фердебобеля? Ага, до фига всего.

В современных IDE типа IntelliJIdea добавление исключения во throws происходит по одному нажатию кнопки или мыши. Но дело даже не в этом.

Игорь Шевченко ©   (21.03.06 18:10) [65]

Я извиняюсь за оверквотинг, но если из-за кривости рук программиста, написавшего Login(...) из него выскочит какой-то другой Exception из неуказанных в сигнатуре метода, то что произойдет и как мне поможет компилятор ?

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


 
FastReporter   (2006-03-22 10:41) [94]

DiamondShark ©   (21.03.06 18:16) [66]

Вы почему throws ZerroDivide нигде не пишете?

Это Run-time (unchecked exception). Незачем писать к каждому методу TOutOfElectricityException :)


 
Игорь Шевченко ©   (2006-03-22 11:31) [95]

FastReporter   (22.03.06 10:40) [93]


> Вы сейчас привели аргумент как раз в пользу CheckedException.
>  В том то и дело, что указанная ситуация попросту невозможна.
>  Будет ошибка компиляции, если кидается недекларированное
> исключение.



> Это Run-time (unchecked exception). Незачем писать к каждому
> методу TOutOfElectricityException :)


Ну вот. А как же тогда недекларированность ? :)


 
Sandman25 ©   (2006-03-22 15:13) [96]

Игорь Шевченко ©   (22.03.06 11:31) [95]

Ох. Представьте себе сложные системы, когда самый последний в цепочке вызовов метод m1 генерирует исключение E1 и E2, вызывающий его m2 перехватывает E1 и сам генерирует E3 и E4, вызывающий его m3 перехватывает E4, добавляет E5,E6,E7 и т.д. Вопрос: насколько просто будет в Delphi отследить, все ли нужные ошибки обработаны и какие остались еще необработанными? А в java в этом поможет компилятор. Причем использовать указанные возможности необязательно (хотя, в принципе, желательно, не зря throws задейцствовано и в javadoc).
В общем, резюмирую. Каждый овощ хорош... (с) Вы :)


 
Игорь Шевченко ©   (2006-03-22 15:28) [97]

Sandman25 ©   (22.03.06 15:13) [96]


> Представьте себе сложные системы, когда самый последний
> в цепочке вызовов метод m1 генерирует исключение E1 и E2,
>  вызывающий его m2 перехватывает E1 и сам генерирует E3
> и E4, вызывающий его m3 перехватывает E4, добавляет E5,E6,
> E7 и т.д. Вопрос: насколько просто будет в Delphi отследить,
>  все ли нужные ошибки обработаны и какие остались еще необработанными?
>  


> Вопрос: насколько просто будет в Delphi отследить, все ли
> нужные ошибки обработаны и какие остались еще необработанными?
>  


Уважаемый Александр, как я уже не один раз говорил, Exception по моим понятиям является исключительной ситуацией, а не механизмом реализации программной логики. Я не спорю, есть и такие программы, поведение которых основывается на возбуждении exceptions и последующей их обработки, только по моему скромному опыту отлаживать такие программы крайне неудобно. Надеюсь, с тем, что программы приходится отлаживать, спорить здесь никто не будет.

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

С наилучшими!


 
Sandman25 ©   (2006-03-22 15:33) [98]

Игорь Шевченко ©   (22.03.06 15:28) [97]

Ладно, всё понятно.

С наилучшими.


 
iZEN ©   (2006-03-22 16:17) [99]

Игорь Шевченко ©   (22.03.06 15:28) [97]
>Уважаемый Александр, как я уже не один раз говорил, Exception по моим понятиям является исключительной ситуацией, а не механизмом реализации программной логики.
>Я не спорю, есть и такие программы, поведение которых основывается на возбуждении exceptions и последующей их обработки, только по моему скромному опыту отлаживать такие программы крайне неудобно.
>Собственно, этот подход и рождает мое непонимание необходимости декларировать порождаемые исключения.

Что делать, если исключительные ситуации возникают в нескольких нитях? Как за этим следить, если есть только один контролирующий механизм, работающий на стадии выполнения приложения в виде непроверяемых на стадии компиляции Runtime Exception"s? Ошибки, рано или позно, в могопоточном приложении будут вылезать наружу, отдельные нити сами-собой будут прекращать существование по непонятным причинам с мерзким системным сообщением об ошибке. Естественно, программистами будут предприниматься меры по пересозданию убитых нитей (что является довольно-таки затратной операцией) в приложении. Хотя всё это можно было оформить в структурированную систему обработки ошибок с привлечением компилятора ещё на стадии проверки кода на корректность.

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

Никто не спорит. Десят лет в Delphi все только так и делали.


 
Игорь Шевченко ©   (2006-03-22 16:34) [100]

iZEN ©   (22.03.06 16:17) [99]


> Ошибки, рано или позно, в могопоточном приложении будут
> вылезать наружу, отдельные нити сами-собой будут прекращать
> существование по непонятным причинам с мерзким системным
> сообщением об ошибке. Естественно, программистами будут
> предприниматься меры по пересозданию убитых нитей (что является
> довольно-таки затратной операцией) в приложении


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


> Как за этим следить, если есть только один контролирующий
> механизм, работающий на стадии выполнения приложения в виде
> непроверяемых на стадии компиляции Runtime Exception"s?
>



> Хотя всё это можно было оформить в структурированную систему
> обработки ошибок с привлечением компилятора ещё на стадии
> проверки кода на корректность


Я извиняюсь, а стуктурированная система какие ошибки будет обрабатывать, которые в рантайм возникают или которые возникают по воле самой программы ?

И, попробую еще раз повторить свою просьбу о примере, наглядно показывающем все преимущества checked-exceptions.


> Десят лет в Delphi все только так и делали.


В java программы не отлаживают ? Просто интересно...


 
iZEN ©   (2006-03-22 17:27) [101]

Игорь Шевченко ©   (22.03.06 16:34) [100], ну что ещё я могу сказать? Слов почти не осталось.

>И, попробую еще раз повторить свою просьбу о примере, наглядно показывающем все преимущества checked-exceptions.

Ну не буду же приводить в качестве примера исходники JUnit и Jakarta Tomcat. Это будет интересно немногим да и места здесь займёт...Но в следующем коде я ходя бы попытаюсь продемонстрировать важность работы с проверяемыми исключениями (улучшенный мной код другого автора):

package ru.skipy.net.protocol.jarres;
/**
* URLConnection implementation for jarres protocol.
* @author Eugene Matyushkin
* @version 1.(1)
*/
import java.io.*;
import java.net.*;
public class JarResourceURLConnection extends URLConnection {
   private String resourcePath;
   private boolean connected = false;
   private InputStream is = null;
   public JarResourceURLConnection(URL url) {
       super(url);
       resourcePath = url.getPath();
   }
   public synchronized void connect() throws IOException {
       if (connected)
           return;
       is = new ByteArrayInputStream(readData());/* в случае исключения выход "вверх по стэку" */
       connected = true;
   }
   private byte[] readData() throws IOException {
       InputStream resourceStream = getClass().getResourceAsStream(resourcePath);
       if (resourceStream == null)
           throw new IOException("Ресурс недоступен.");
       ByteArrayOutputStream baos = new ByteArrayOutputStream();
       DataInputStream dis = new DataInputStream(resourceStream);
       byte[] buffer = new byte[16384];/* такое ограничение когда-нибудь аукнется */
       while (true) {
           int readed = dis.read(buffer);
           if (readed == -1)
               break;
           if (readed > 0)
               baos.write(buffer, 0, readed);
       }
       return baos.toByteArray();
   }
   public synchronized InputStream getInputStream() throws IOException {
       try {
           connect();
       } catch (IOException ioex) {
           /* Вот здесь и ловим IOException "Ресурс недоступен." и отправляем его дальше с дельной информацией */
           throw new FileNotFoundException(resourcePath + " - "
               + ioex.getMessage());
       }
       return is;/* отдаём ссылку, если всё в порядке */
   }
}


Проверяемые исключения дисциплинируют и направляют принятие решения о структурированной обработке исключений, а не о разбросанности по разным местам методов-ловцов всеможных ракообразных, встречающихся в тёмных "водах" Windows и в чужих плохо документированных библиотеках.

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


 
Игорь Шевченко ©   (2006-03-23 10:10) [102]


> Проверяемые исключения дисциплинируют и направляют принятие
> решения о структурированной обработке исключений


Что в данной фразе подразумевается под "структурированностью" ?

Теперь по коду:

1) не разумнее было бы (в данном конкретном случае), чтобы метод connect выбрасывал исключение EConnectError или EResourceUnavailable, вместо того, чтобы засорять мозги программисту ( компилятору) необходимостью запоминать, что при вызове connect и возникновении IOException необходимо сделать вывод о недоступности ресурса.
2) внутри методов выделяется память. Почему не написано, что метод connect может возбудить EOutOfMomery ?
3) зачем я указываю, что метод connect выбрасывает IOException - внутри метода явного throw нет, а запоминать, какие вызываемые методы какие исключения могут выбросить - а какой в этом глубокий смысл ? Кроме того, я не вижу, чтобы метод connect обрабатывал другие типы исключений, оставляя необработанным только IOException, чем и как мне в этом случае может помочь компилятор ?


 
iZEN ©   (2006-03-23 10:55) [103]

>Игорь Шевченко ©   (23.03.06 10:10) [102]
>> Проверяемые исключения дисциплинируют и направляют принятие решения о структурированной обработке исключений
>Что в данной фразе подразумевается под "структурированностью" ?

"Структурированность" здесь подразумевает одиный путь генерации и ловли известных исключений, а не "try/catch(Throwable anyEx) в нужных местах" (не нужно будет бить голову тому, кто это напишет).

>Теперь по коду:

>1) не разумнее было бы (в данном конкретном случае), чтобы метод connect выбрасывал исключение EConnectError или EResourceUnavailable, вместо того, чтобы засорять мозги программисту ( компилятору) необходимостью запоминать, что при вызове connect и возникновении IOException необходимо сделать вывод о недоступности ресурса.

Зачем плодить лишние сущности? Достаточно исключения ввода-вывода. Заметь, внутри класса генерируется только одно унифицированное исключение — IOException, конкретный экземпляр FileNotFoundException является его потомком, поэтому при желании пользователь этого класса может привести исключение к этому типу и получить, таким образом, конкретное описание ошибки. Но в большинстве случаев такой детальной информации не требуется, достаточно общего вида ошибки, что и отражено в сигнатурах методов.

>2) внутри методов выделяется память. Почему не написано, что метод connect может возбудить EOutOfMomery ?

Исключение OutOfMemoryError в Java (и в C#, и в Delphi) является непроверяемым исключением (и к тому же системной ошибкой в Java, приводящей к краху JVM, что в данном случае несущественно). Объявление непроверяемых исключений в списке throws ни к чему не обязывает компилятор. Компилятор следит за правильным использованием только проверяемых исключений. То есть OutOfMemoryError потенциально может произойти абсолютно в любом методе, throws для него не нужен.

>3) зачем я указываю, что метод connect выбрасывает IOException - внутри метода явного throw нет, а запоминать, какие вызываемые методы какие исключения могут выбросить - а какой в этом глубокий смысл ?

Метод cjnnect() не перехватывает (нет блока try/catch) исключений, которые могут произойти в методе readData(), а передаёт их вверх по стэку вызова. Просто мне удобнее здесь дать пользователю возможность использовать дуальность API этого класса: в одном случае использовать state-machine-model с пошаговым протоколом установления соединения и получения данных (connect(), getInputStream()), в другом случае использовать функциональный подход с вызовом метода как функции (просто getInputStream()). В обоих случаях семантика вызовов разная (можно использовать по-разному), но класс работает одинаково (меньше ошибок кода).

>Кроме того, я не вижу, чтобы метод connect обрабатывал другие типы исключений, оставляя необработанным только IOException, чем и как мне в этом случае может помочь компилятор ?

Зачем ещё что-то обрабатывать? Компилятор обращает внимание только на правильное использование IOException (делай try/catch в теле или throws в сигнатуре, иначе не буду компилировать), больше он ни о чём мне не говорит. Это же он скажет пользователю, который будет использовать данный библиотечный класс при любой семантике вызова.


 
Игорь Шевченко ©   (2006-03-23 11:11) [104]

iZEN ©   (23.03.06 10:55) [103]


> Просто мне удобнее здесь дать пользователю возможность использовать
> дуальность API этого класса: в одном случае использовать
> state-machine-model с пошаговым протоколом установления
> соединения и получения данных (connect(), getInputStream()),
>  в другом случае использовать функциональный подход с вызовом
> метода как функции (просто getInputStream()). В обоих случаях
> семантика вызовов разная (можно использовать по-разному),
>  но класс работает одинаково (меньше ошибок кода).


Переведи на понятный язык.


> Зачем плодить лишние сущности? Достаточно исключения ввода-
> вывода.


А оно как-то семантически связано с методом connect ? Для меня, например, первый раз увидевшего этот код (это вообще-то важный момент), никакой связи между connect и ошибкой ввода-вывода не усматривается.


> Зачем ещё что-то обрабатывать? Компилятор обращает внимание
> только на правильное использование IOException (делай try/catch
> в теле или throws в сигнатуре, иначе не буду компилировать),
>  


Я правильно понял, что если некий метод обращается к неким методам, в сигнатуре которых написано, что они throws некие exceptions, то этот метод либо обязан выполнять try/catch именно этих exceptions либо переносить их в свою сигнатуру ?


 
iZEN ©   (2006-03-23 11:57) [105]

>Игорь Шевченко ©   (23.03.06 11:11) [104]
>Переведи на понятный язык.

Есть разные решения одной и той же задачи. В одном случае пользователю требуется машина состояний (у него могут быть свои причины: типа плагин-оболочку делает к какой-то системе), в другом случае нужно просто получить байтовый поток.

>> Зачем плодить лишние сущности? Достаточно исключения ввода-вывода.
>А оно как-то семантически связано с методом connect ? Для меня, например, первый раз увидевшего этот код (это вообще-то важный момент), никакой связи между connect и ошибкой ввода-вывода не усматривается.

Семантика соединения в Java связана с вводом-выводом.

> Зачем ещё что-то обрабатывать? Компилятор обращает внимание
> только на правильное использование IOException (делай try/catch
> в теле или throws в сигнатуре, иначе не буду компилировать),
>>Я правильно понял, что если некий метод обращается к неким методам, в сигнатуре которых написано, что они throws некие exceptions, то этот метод либо обязан выполнять try/catch именно этих exceptions либо переносить их в свою сигнатуру ?

Да. И за этим жёстко следит компилятор. Компилятор не будет компилировать, если ни одно из этих условий не соблюдено. В этом вся соль Checked Exception"s.


 
Игорь Шевченко ©   (2006-03-23 12:11) [106]

iZEN ©   (23.03.06 11:57) [105]


> Есть разные решения одной и той же задачи. В одном случае
> пользователю требуется машина состояний (у него могут быть
> свои причины: типа плагин-оболочку делает к какой-то системе),
>  в другом случае нужно просто получить байтовый поток.


Да, сообразил.


> Да. И за этим жёстко следит компилятор. Компилятор не будет
> компилировать, если ни одно из этих условий не соблюдено.
>  В этом вся соль Checked Exception"s.


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

Кроме того, в одном из предыдущих постов, ты говорил, "зачем плодить лишние сущности" имея в виду ненужность создания EConnectError и утверждая, что IOException достаточно.
В таком случае, зачем введена лишняя сущность FileNotFoundException в методе getInputStream ? И почему не указано, что метод getInputStream throws FileNotFoundException ?


 
wicked ©   (2006-03-23 12:28) [107]

позволю себе вставить свои 5 коп...
> Игорь Шевченко ©   (23.03.06 12:11) [106]
> > Да. И за этим жёстко следит компилятор. Компилятор не
> будет
> > компилировать, если ни одно из этих условий не соблюдено.
>
> >  В этом вся соль Checked Exception"s.
>
>
> Мне все-таки кажется, что это лишняя нагрузка на программиста,
>  которому надо следить за всем возбуждаемыми исключениями
> в вызываемых методах.

когда-то пришлось делать один маленький проект на java и тогда я столкнулся с checked exceptions.... сначала было неприятно, что валидный, в общем то, код не компилируется... потом таки я понял, что таким образом разработчики насаждают аккуратность обработки ошибок, что не есть плохо.....
имхо, для того, чтобы оценить перелесть/ужас checked exceptions, нужно просто с ними поработать....
в любом случае, они есть в java и с этим уже ничего не поделаешь..... ;)


 
Суслик ©   (2006-03-23 12:33) [108]

Позвольте встряну.

Я неплохо знаю java. Могу сказать так, что мне в дельфи при реализации библиотек РАЗНЫМИ членами коллектива очень не хватает формального контракта между мной (пользователем библиотеки) и ей (библиотекой) в области разделения ответственности за обработку исключений (НЕ ошибок!!!). Мы сейчас делаем так, что в местах смычек кода, который разработан разными людьми, документируем семантику методов с использованием секции, аналогичной throws. Т.е. описываем те исключения, которые возбуждает метод из биболиотеки и которые несут семантическую нагрузку, на которую ОБЯЗАН реагировать пользователь библиотеки. Лично мне очень не хватает поддержики компилятором контроля за выполнением программастом-клиентом своих обязанностей по обработке исключений.


 
Игорь Шевченко ©   (2006-03-23 12:53) [109]

Суслик ©   (23.03.06 12:33) [108]


> Могу сказать так, что мне в дельфи при реализации библиотек
> РАЗНЫМИ членами коллектива очень не хватает формального
> контракта между мной (пользователем библиотеки) и ей (библиотекой)
> в области разделения ответственности за обработку исключений
> (НЕ ошибок!!!).


То есть, у вас в библиотеке логика построена на обработке исключений ? Или я не так понял ?


 
iZEN ©   (2006-03-23 13:20) [110]

>Игорь Шевченко ©   (23.03.06 12:11) [106]
>Мне все-таки кажется, что это лишняя нагрузка на программиста, которому надо следить за всем возбуждаемыми исключениями в вызываемых методах.

Кому-то, действительно, "лишняя".

>Кроме того, в одном из предыдущих постов, ты говорил, "зачем плодить лишние сущности" имея в виду ненужность создания EConnectError и утверждая, что IOException достаточно.
>В таком случае, зачем введена лишняя сущность FileNotFoundException в методе getInputStream ? И почему не указано, что метод getInputStream throws FileNotFoundException ?

Порой детали не так важны, но в случае надобности их можно получить:
FileNotFoundException fnex = (FileNotFoundException)ioex;
Я предпочёл более общий вариант исключения более детальному.

Кстати, есть пример подобного рода.
На собеседовании спрашивают, почему лучше иметь объект более абстрактного типа, чем конкретного, почему следующее выражение:
Map map = new HashMap();
более предпочтительнее, чем это:
HashMap map = new HashMap();
если вид контейнера определён только для API Map?

Всегда лучше исксусственно ограничить себя в возможностях, чем использовать лишь часть из общедоступных. В данном случае класс HashMap реализует интерфейс Map, но в программе нигде не используются дополнительные возможности HashMap, это просто контейнер с публичным интерфейсом. Хотя в любой момент можно расширить доступ к объекту путём приведения его к тому типу, кем он на самом деле является:
HashMap map2 = (HashMap)map;
где map2 — это ссылка на тот же самый объект, на который ссылается map.
После этого можно использовать расширенные свойства объекта, но только по ссылке map2.

Использование более общего IOException вместо конкретизированного потомка FileNotFoundException в примере выше — из той же оперы.


 
Игорь Шевченко ©   (2006-03-23 14:11) [111]

iZEN ©   (23.03.06 13:20) [110]


> Использование более общего IOException вместо конкретизированного
> потомка FileNotFoundException в примере выше — из той же
> оперы.


А использование более общего предка Throwable ? ;)


 
Суслик ©   (2006-03-23 14:12) [112]


>  [109] Игорь Шевченко ©   (23.03.06 12:53)
> То есть, у вас в библиотеке логика построена на обработке
> исключений ? Или я не так понял ?


(пожалуйста, прочти до конца:))

Нет. Не логика библиотеки построена на исключениях, а логика обработки непозитивной реакции библиотеки.

Вот пример. Ты знаешь, что я занимаюсь мат. моделями в экономике и образовательными программами на их основе. У нас сейчас программу пишут 2 человека. Объектная модель мат. модели совершенно обособлена. У нее есть 5-6 методов, с помощью которых на модель может воздействовать второй программист.

При этом есть одна генеральная правильная линия общения - все работает ОК. Т.е. второй программист добивается от моей модели того поведения, которое указано в имени метода. Но при этом есть исключительные случаи, когда задача, полученная моей моделью не может быть выполнена.

Что мне делать, чтобы сообщить второму программисту, об ошибке?
1. Возвращать код результата - число. Этот вариант совсем плох, т.к. если он забудет обработать ошибочный ответ, то никто не узнает о том, что была ошибка.
2. Возбудить исключение. Это лучше. Но этого недостаточно, т.к. исключения несу, скорее, смысловую нагрузку, чем информацию об ошибках. Поэтому просто бросить исключение и думать, что на него кто-то среагирует мне не всегда достаточно. Я хочу заставить второго программиста среагировать на исключение, потому как это не ошибка, а часть поведения программы.

Надеюсь, понятно.


 
Игорь Шевченко ©   (2006-03-23 14:13) [113]

Суслик ©   (23.03.06 14:12) [112]


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


Чем это отличается от


> у вас в библиотеке логика построена на обработке исключений


?


 
Суслик ©   (2006-03-23 14:14) [114]

добавлю, ясное дело, что от дурака защититься сложно - второй программист может поставить просто заглушку. Но тогда он будет не второй программист, а 132 где нить в другом месте, а не у меня :)


 
Суслик ©   (2006-03-23 14:15) [115]


>  [113] Игорь Шевченко ©   (23.03.06 14:13)

Я не понял, ты хочешь на [113] получить ответ или услышать пример использования checked exceptions? :)


 
Игорь Шевченко ©   (2006-03-23 14:17) [116]

Суслик ©   (23.03.06 14:15) [115]

Пример использования мне написали в [101].

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

"Плавали, знаем" (с) мореплавание Солнышкина.


 
Суслик ©   (2006-03-23 14:18) [117]


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

У тебя есть альтернативы для примера из [112]?
В студию, пожалуйста.


 
Игорь Шевченко ©   (2006-03-23 14:20) [118]


> 1. Возвращать код результата - число. Этот вариант совсем
> плох, т.к. если он забудет обработать ошибочный ответ, то
> никто не узнает о том, что была ошибка.
> 2. Возбудить исключение. Это лучше. Но этого недостаточно,
>  т.к. исключения несу, скорее, смысловую нагрузку, чем информацию
> об ошибках. Поэтому просто бросить исключение и думать,
> что на него кто-то среагирует мне не всегда достаточно.
> Я хочу заставить второго программиста среагировать на исключение,
>  потому как это не ошибка, а часть поведения программы.


Я бы код возвратил.


 
Думкин ©   (2006-03-23 14:21) [119]

А если он забудет обработать код - то будет работать 133-м где-то тоже далеко.


 
pasha_golub ©   (2006-03-23 15:14) [120]

Дык, а почему нельзя сделать унифицированный обработчик возвращаемого кода?

типо

procedure Check(ErrCode: integer);
begin
case ErrCode of
 ERR_FILE_NOT_FOUND: raise EFileNotFound.Create("blablabla");
 ERR_...
end;
end;

Соответственно вызов метода будет

Check(GetSizeOfSomeFile("path"));

Пример взят из той же самой Делфи, модуль DbTables.pas, где процедура Check выглядит как:


procedure Check(Status: DBIResult);
begin
 if Status <> 0 then DbiError(Status);
end;



Страницы: 1 2 3 4 вся ветка

Форум: "Прочее";
Текущий архив: 2006.04.16;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.77 MB
Время: 0.052 c
2-1144192096
Tester83
2006-04-05 03:08
2006.04.16
Проблема со шрифтами


15-1143217541
Ученик чародея
2006-03-24 19:25
2006.04.16
Принтсервер Surecom EP-903X-U печать из DOS-а.


15-1142567328
Monitor Search
2006-03-17 06:48
2006.04.16
Помогите выбрать монитор.


15-1143021838
Nsk3D
2006-03-22 13:03
2006.04.16
Шрифты.создание.модификация.


11-1124357132
Domix
2005-08-18 13:25
2006.04.16
Динамическое создание форм из консоли





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский