воскресенье, 23 мая 2010 г.

Java: finally + return всё стерпит

Конструкция try-catch-finally в Java. Finally выполняется всегда. Это знают все. А что если в finally стоит return, а в try или catch случился exception? 

Вот такой примерчик. Предположим у нас есть наш собственный checked my.ArithmeticException которым мы оборачиваем стандартный unchecked ArithmeticException по каким-то своим причинам. Как-то так:

  1. public int myDiv(int a, int b) throws my.ArithmeticException{
  2.     int result = 0;
  3.     try{
  4.          result = a / b;
  5.     }
  6.     catch (java.lang.ArithmeticException arex){
  7.          throw new my.ArithmeticException("Division by zero", arex);
  8.     }
  9.     finally{
  10.         return result;
  11.     }

Запускаем. Для входных параметров 12345 и 0 (деление на 0) наш exception не бросается а результат операции равен нулю.

Что же произошло? Почему отработал return а не throws?

Разберемся, как работает JVM при выходе из метода. Выход из метода - значение на стеке. И throws и return занимают её место, когда работа метода завершается. В нашем случае, в стек сначала попадает throws my.ArithmeticException, затем начинает работать finally который кладет на стек return и перетирает наш exception. Он теряется. Навсегда.

Как это может быть полезно? Да никак. Если уж очень надо чтобы метод всегда завершал работу штатно (например) , обычно пишут catch(Throwable) в котором хотя бы можно залогировать проблему перед тем как ее игнорировать. Finally + return затирает ВСЕ (да-да, и OutOfMemory тоже) exception'ы и вы никак об этом не узнаете.

Наверное единственный правильный вывод к которому я пришел - не писать return в finally.

воскресенье, 16 мая 2010 г.

XML

Последнее время часто слышу недовольство XML.

  1. Медленный (в смысле маршаллинга/де-маршаллинга)
  2. Слишком низкое отношение сигнал/шум (то есть на каждое значение приходится пара тегов и/или аттрибут - а это все буквы/байты) для использования XML протоколов в сети
  3. XML-валидация по факту не работает. То есть работает на стороне того, кто XML отправляет (можно сразу понять что хотим послать невалидный XML и что-то с этим сделать). На стороне же приемника XML-документа чаще всего в реальной системе нужно некорректные поля просто отбросить и обработать хотя бы то, что пришло. Чем просто падать - мол, входной документ невалиден и всё тут.
  4. Слабое распространение XML схем в предметных областях. Например, в электронной торговле придумали FpML, который по идее должен был описывать все возможные варианты электронных сделок. По факту, всегда найдется какое-нибудь значение/свойство экзотического финансового инструмента, которое нельзя корректно положить в FpML - не хватает элемента или тэга. Простота создание XML схемы порождает сильное желание написать её самому, а не искать и разбираться в чужой. Как следствие, чуть ли не каждый финансовый институт добавляет собственное расширение FpML, и смысл единого стандарта теряется. 

Во всем этом безусловно есть смысл. Наверное, на пике XML-эйфории его стали бездумно пихать во все решения (см. Золотой молот) - и в конфиги, и в протоколы между высокопроизводительными приложениями, и в кодогенерацию, и да мало ли куда еще. Вот народ и "наелся" :)

суббота, 1 мая 2010 г.

Задачка про мальчиков

Еще одна задача. Такую не знал. Мне кажется ответ: 0,33.

Изначально расклад такой:

М+М

М+Д

Д+М

Д+Д

вероятность каждой комбинации 0,25. Теперь мы узнаем что один ребенок - точно мальчик. Вариант Д+Д отпадает. Остается три равновариантных ответа.