Месяц: Июль 2011

  • Java 7. Строки в переключателе


    В предыдущей статье я написал про некоторые новшества в Java 7
    (входящие в Project Coin) а именно:

    – Бриллиантовый оператор (Improved type inference for generic instance creation diamond)
    – Автоматически закрывающиеся ресурсы (try-with-resource).

    Конечно, это очень приятные вещи, но больше всего я рад появлению Strings in switch!
    Возможность использовать строки в switch люди ждут уже (далее…)

  • Дельфин, монета и бриллиантовый оператор.

    Релиз Java 7 должен выйти 28 Июля.
    В связи с этой знаменательно датой, я наконец-то решил посмотреть, что нас всех ждет. Поскольку в последнее время в основном занимаюсь Scala, то на новые языковые фичи в Java не обращал серьезного внимания (только на тусовках java-программистов, плюс поглядывал что пишут в разных блогах жависты).

    Итак Java 7.
    Продолжая традиции именования (Java 5 – тигр, Java 6 – мустанг), у нового релиза кодовое имя “Дельфин”.
    Список фич можно посмотреть здесь: http://www.oracle.com/technetwork/java/7-138633.html.

    Технических новшеств очень много. Среди них самое интересное место занимает так называемый “Проект Монета (Project Coin)“.
    (далее…)

  • do while false

    “Делать пока ложно”.

    Пару дней назад пытался кратко рассказать товарищу через аську про использование
    do { } while(false); для переписывания длинных ветвящихся if-ов.

    Кратко объяснить не получилось, в итоге решил написать в блоге.

    Метод довольно спорный, хотя и встречается в некоторых авторитетных источниках (например
    в “Совершенном Коде” С. Макконела).

    Идея довольно простая.
    0. Код помещаем в “do { …много_кода… } while(false);” блок. Если что-то не так вызываем break.
    1. Оператор break перекинет нас в конец блока do.
    2. Поскольку указан while(false), то повторного выполнения кода не будет.

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

    Примитивный (выдуманный) пример:

            boolean error = false;
            if (x > 10) {
                error = true;
            } else if (x > 0 && x < = 10) {
                y = foo();
                if (y > 0 && y < 10) {
                    error = true;
                } else {
                    x = y;
                }
            } // много if-else кода
            
            if (!error) {
                doSomething(x, y);
            }
    

    С помощью break-ов такой код приобретает более понятный (не для всех!) вид.

        do {
                if (x > 10) {
                    break;
                } 
                
                if (x > 0 && x < = 10) {
                    y = foo();
                    if (y > 0 && y < 10) {
                        break;
                    } else {
                        x = y;
                    }
                }
                // много кода для проверок
                doSomething(x, y);
            } while (false);
    
  • Firefox и localhost

    Недавно помогал ребятам из одной конторы (нужно было сделать на HTML5 Canvas графический редактор для их легаси-системы). Среди прочих задачек, была интересная проблемка с Firefox-ом – медленно обрабатывались запросы (1 запрос > 1 секунды).
    Так как веб-сервер – самописный (полностью!), то были подозрения на все-что угодно (ошибки в реализации протокола, проблемы в клиентском коде на javascript и т.д.).

    В итоге все-таки я проблему решил, оказалось очень забавно. Пишу здесь, может кому пригодится.
    Сервер тестировался на localhost-е, а в Firefox-е есть проблема http://goo.gl/jJc7g
    В общем проблема заключалась в медленном DNS-ресолве для localhost в Firefox-e (например 127.0.0.1 – не глючил)

    Самое просто решение (но не самое правильно):
    about:config -> network.dns.disableIPv6=true

    Подробнее о причинах и правильных решениях: http://kb.mozillazine.org/Network.dns.disableIPv6

  • Мои хинты для Netbeans 7

    Недавно нужно было заново установить Netbeans 7.
    Вот некоторые действия, которые всегда приходится делать после установки “коробочной” версии,
    а именно: поддержка Scala, интерфейс на английском и quick file chooser.

    Установка

    Заходим на официальный сайт: netbeans.org
    Нажимаем на [Download FREE] и переходим на ссылку http://netbeans.org/downloads/index.html
    Скачиваем, устанавливаем и запускаем.

    Итак, что приходится делать:

    0. Обновления.

    На всякий случай проверить наличие обновлений:
    Меню → Help → Check for Updates

    1. Русский → English

    Чтобы вернуть обратно английский нужно:
    – Найти файл “netbeans.conf” (для Windows-пользователей: он должен находится где-то здесь – “C:\Program Files\NetBeans 7.0\etc\” )
    – Указать в настройках –locale en:US

    netbeans_default_options="МНОГО_БУКВ   --locale en:US"
    

    UPD: Почистить домашнюю папку “.netbeans/7.x” перед сменой локали, а то “Службы” и некоторые другие сообщения могут остаться на русском. Предварительно сделайте бэкап.

    2. File Chooser

    Сразу же установить плагин Quick File Chooser:
    Меню → Тools → Plugins → Available Plugins
    Это намного более шустрый и удобный (на мой взгляд) диалог для выбора файлов.

    3. Scala

    Ставим plugin для работы со Scala.
    Для версии 2.8.x: http://plugins.netbeans.org/plugin/36598/nbscala-2-8-x
    Подробнее можно прочитать на вики нетбинсов:
    http://wiki.netbeans.org/Scala
    или на портале с плагинами:
    http://plugins.netbeans.org/

  • Scala и пустота

    В Scala есть несколько разных сущностей для обозначения несуществующих, пустых или неопределенных объектов.
    Начнем с самого привычного для Java-программистов случая.

    Null

    Null – это trait. Объект null (с маленькой буквы) — это как раз и есть объект типа Null. Он находится внизу иерархии типов в Scala, в противовес AnyRef.
    Благодаря этому вы всегда можете как-бы “занулить” любую ссылку, т.е. присвоить ссылки значение null:

    scala> var x = "String"
    x: java.lang.String = String
    scala> var i = List(3)
    i: List[Int] = List(3)
    scala> i = null
    i: List[Int] = null
    scala> x = null
    x: java.lang.String = null
    

    Null работает только для ссылочных типов, для более общего случая, есть “ничто (Nothing)” .

    Nothing

    Nothing – это тоже trait. Nothing находится на самом дне иерархии типов, в противовес Any. Соответственно, это более общий тип, чем Null и подходит даже для AnyVal объектов (числа, буквы, правда/ложь и т.д.).

    В отличие от Null, Nothing не может иметь экземпляров (на то оно и ничто).
    Другими словами нет аналога null для Nothing.

    Возникает вопрос, где такое самое “нижнее ничто” может использоваться?
    В документации по API можно найти несколько примеров:

    // пакет scala.sys
    def error(message: String): Nothing = throw new RuntimeException(message)
    

    Этот метод никогда ничего не возвращает, поэтому возвращаемый тип Nothing.

    Unit

    Unitкласс, чем-то похоже на void, который используется в Java. В Scala тип Unit применяется тогда, когда нужно показать, что функция возвращает пустое значение (но все-таки что-то возвращает, хоть и пустое).

    Если открыть документацию, то можно увидеть что:

    class Unit extends Any with AnyVal
    

    Внимание! AnyVal, а не AnyRef. Это значит, что Unit это не ссылочный тип ( в отличие от Null). Можно сказать, что Unit-у как бы “ближе по родству” будут числа, буквы и другие примитивные типы (которые тоже AnyVal).

    В отличие от Nothing, Unit повезло больше. Он может иметь свой объект, правда в единственном экземпляре. Он обозначается двумя круглыми скобками: (). Например:

    scala> val u = ()
    u: Unit = ()
    

    Другими словами Nothing уместен тогда, когда функция в принципе ничего не возвращает, а Unit – это когда возвращает, но оно пустое.
    Это отличие существенно. Например результат вызова функции с Unit может быть присвоено (в Java с void такой фокус не выйдет).

    scala> def foo():Unit = {}
    foo: ()Unit
    scala> val u = foo()
    u: Unit = ()
    

    Nil

    Nilобъект, пустой список (extends List[Nothing]).
    Поскольку Nil – это список, хоть и пустой, у него как у любого списка есть метод :: (два двоеточия), с помощью которого удобно создавать списки:

    scala> var x = 1 :: 2 :: Nil
    x: List[Int] = List(1, 2)
    

    Это возможно благодаря тому, что название метода заканчивается на : (двоеточие), в таком случае метод применяется к правому операнду (работает для операторной нотации вызова метода).

    Другими словами, это аналогично вызову: (Nil.::(2)).::(1)

    None

    None – это такой хитрый объект (extends Option[Nothing]) , который используется в случае, если мы хотим получить что-то, например, из Map, а его там нет.

    Например:

    scala> var m = Map(1->2)
    m: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2)
    scala> val n = m.get(100)// ну нет такого элемента
    n: Option[Int] = None
    

    None примечателен тем, что:

    • это объект (т.е. синглтон)
    • это кейс-объект
    • наследуется от Option[Nothing]

    В случае попытки получить значение (вызвав метод n.get()), мы получим исключение:java.util.NoSuchElementException.

    Если у None вызывать метод isEmpty() – мы получим true.

    Поскольку None – объект кейс-класса, то мы можем его “матчить” (сопоставлять по шаблону).

    scala> n match { 
     case Some(x) => println("x:" + x) 
     case None => println("none") 
    }
    

    Если у None вызвать метод toList – мы получим пустой список (т.е. Nil).

    scala> n.toList() == Nil
    res21: Boolean = true
    

    Поскольку None объявлен как extends Option[Nothing], а Nothing – “самое нижнее ничто”, то None может работать с любыми типами (как с ссылочными так и с примитивными).

  • EncryptableProperties и защита от дурака

    Все знают, что не следует хранить в конфигурационных файлах (например properties) критически важную информацию в открытом виде.
    Например логины и пароли от базы данных, почты и т.д.
    Не стоит этого делать, т.к. “случайный” сисадмин или пользователь сможет открыть этот ваш файлик и увидеть пароль.

    С учетом того, что довольно часто пароли придумывают люди, то запомнить их бывает очень просто.
    Более того, некоторые пароли настолько поражают воображение, что их очень сложно забыть. Как правило они выглядят так: 123456, sa, manager и т.д…
    Конечно это личное дело каждого, но выставлять на обозрения такие свои пароли, как-то не совсем прилично.

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

    Как вариант можно использовать Jasypt. Этот довольно большой проект и его можно использовать и в других целей, но мы будем разбирать простой и конкретный случай: предотвратить хранение паролей в открытом виде в properties файле.
    Главное, что нужно понимать, мы не строим защиту от серьезного злобного хакера, а делаем простую защиту от дурака!

    Для этого: (далее…)