Метка: Java

  • printf

    Небольшой справочник “для себя” по работе с джавным printf().

    Для простоты текста заменил System.out.printf() на printf().

    Базовые конструкции.

    %s → String или toString().

    printf("Hello %s!", "World"); //  "Hello World!"
    

    %n → Перенос строки.

    Byte, Short, Int, Long.

    %d → В десятеричном.
    %x → В шестнадцатеричном.

    %7d → В десятеричном. Минимальная ширина строки 7 знаков.

    printf("%7d", 1); //  "      1"

    %07d → Минимальная ширина строки 7 знаков. Начало забить нулями.

    printf("%07d", 1); //  "0000001"

    Float, Double.

    %f → Десятичное  число с точкой.
    %e → Десятичное  число с точкой и экспонентой.

    %.10f → С точностью 10 знаков после запятой.

    printf("%.10f", Math.PI); //  "3,1415926536"

    Date, Calendar.

    %tF → Дата в формате “год-месяц-день”.

    printf("%tF", new Date()); //  "2011-01-27"

    %tT → Время в формате “час:минута:секунда”.

    
    
    printf("%tT", new Date()); //  "22:42:37"
    
  • GWT. Обработка серверных исключений на клиенте.

    В целом обработка исключений при работе в GWT через RPC довольно детально описана в разделе документации DevGuideHandlingExceptions

    Важный момент на который следуют обратить внимание – throws для метода.

    Например, вот Ваш интерфейс:

    public interface MyService extends RemoteService {
      public String myMethod(String s);
    }

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

    Это конечно удобно, т.к. полученный тип исключений является Unchecked Exception. Таким образом его не нужно явно декларировать, оно может произойти где угодно (не надо прописывать везде throws) и такое исключение Вы не обязаны явно отлавливать. 

    Другими словами,  мы же не пишем для каждого метода throws RuntimeException!

    Тем не менее, если где-то у Вас в программе произойдет это исключение:

    public class MyServiceImpl extends RemoteServiceServlet implements
        MyService {
    
      public String myMethod(String s) {
        // Do something interesting with 's' here on the server.
        if (isError() ) { throw new MyException("ups");  
        // 
        return s;
      }
    }

    То это исключение в методе onFailure(Throwable caught) будет передано просто как InvocationException, а не как MyException!
    Дело в том, что если заглянуть в реализацию метода обработки вызова RPC-вызовов:

    RemoteServiceServlet. processCall() → RPC.invokeAndEncodeResponse() → RPC.encodeResponseForFailure() → RPCServletUtils.isExpectedException()
    мы найдем использование следующей конструкции:

    Class< ?>[] exceptionsThrown = serviceIntfMethod.getExceptionTypes();
    

    Другими словами, если Вы хотите чтобы Ваше исключение попадало в onFailure(Throwable caught) как MyException, то нужно обязательно декларировать throws, даже если Ваше исключение extends RuntimeException!

    В нашем примере это будет выглядеть так:

    public interface MyService extends RemoteService {
      public String myMethod(String s) throws MyException;
    }
    

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

  • Самый лучший Singleton

    Из всех существующих на момент написания этого поста реализаций шаблона Singleton (одиночка) мне больше всего нравится эта:

     public class Singleton {
       // Private constructor prevents instantiation from other classes
       private Singleton() {}
    
       /**
        * SingletonHolder is loaded on the first execution of Singleton.getInstance()
        * or the first access to SingletonHolder.INSTANCE, not before.
        */
       private static class SingletonHolder {
         private static final Singleton INSTANCE = new Singleton();
       }
    
       public static Singleton getInstance() {
         return SingletonHolder.INSTANCE;
       }
     }
    

    Эту реализацию придумал  Bill Pugh. Это гениальный и очень простой способ. При помощи элегантного использования внутреннего класса Вы получаете ленивый (объект Singleton не инициализируется до моменты вызова метод getInstance())  и потоко-безопасный Singleton.

    Поскольку в классе Singleton нет статических полей которые нужно инициализировать, класс беспрепятственно загрузится. То есть Вам не нужно ждать, пока мы создадим объект Singleton в самом начале, когда загружаются классы.
    Смотрим дальше, когда объект INSTANCE будет создан? Тогда, когда мы вызовем метод getInstance(), что повлечет загрузку внутреннего класса SingletonHolder, что спровоцирует создание объекта INSTANCE. Поскольку фаза инициализации класса гарантировано (спецификацией) “не конкурента“, то у нас нет необходимости использовать synchronized и volatile. Ура!

  • Звездочка (*) в шестёрке и хитрые bat-файлы

    Запуск java-программы из командной  строки.

    Представим такую ситуацию

    В результате вашей работы в качестве java программиста у вас получился один JAR-файл (для простоты назовем его mytools-1.0-SNAPSHOT.jar). Кроме него вы планируете использовать более десятка других jar-файлов.

    Ваша программа должна запускаться из командной строки, а не из супер-пупер IDE которую вы обычно используете в работе. Например Вашу программу нужно отправить другому человеку, у которого нет такой же как у вас среды разработки (Eclipse, NetBeans, IDEA и т.д.) или запустить на удаленном сервере доступ к которому осуществляется только через SSH. Таким образом, для запуска вашей программы вам нужно собрать все требуемые для работы jar-файлы, прописать их  в CLASSPATH и для удобства написать простой runme.bat файл или (runme.sh для линукса).

    Рецепт 1.

    Требуется: maven, maven-assymbly-plugin

    Если вы используете maven, то возможно Вам будет удобно воспользоваться  maven-assymbly-plugin. Найти информацию по нему можно здесь: http://maven.apache.org/plugins/maven-assembly-plugin/

    В результате вы можете собрать в один JAR-файл, который содержит всё необходимое для работы.

    Для этого:
    1. добавляем в pom.xml настройки для maven-assymbly-plugin.

    <project>
      [...]
      <build>
        [...]
        <plugins>
          <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.2-beta-5</version>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
            </configuration>
            [...]
    </project>

    2. Запускаем сборку

    mvn assembly:assembly

    3. Получаем jar файл со всеми зависимостями:

    target/mytools-1.0-SNAPSHOT-jar-with-dependencies.jar

    Подробную информацию как работать со сборками можно получить открыв ссылку приведенную выше.

    Дальше, я предпочитаю копировать jar-файл в отдельную папку lib. После этого остается только создать простой BAT-файл в котором будет содержаться строка:

    java -cp mytools-1.0-SNAPSHOT-jar-with-dependencies.jar com.programmisty.Main %*

    %* – означает что все аргументы командной строки будут переданы в main-класс.

    Минусы: Если необходимо заменить только одну зависимость, приходится распаковывать и перепаковывать весь этот монолитный jar-файл.

    Рецепт 2

    Собираем все необходимые jar-файлы в одну директорию. Например с помощью maven это можно сделать командой

    mvn dependency:copy-dependencies

    Если вы не используете maven, можно просто скопировать руками все необходимые вам файлы.
    Затем копируем наш mytools-1.0-SNAPSHOT-jar и все дополнительные jar-файлы в папку lib.

    Если у нас windows, создаем BAT-файл runme.bat. В итоге у нас получается что-то вроде этого:

    .
    |_lib
    | |_mytools-1.0-SNAPSHOT-jar
    | |_commons-lang-2.4.jar
    | |_commons-logging-1.1.1.jar
    | |_commons-httpclient-3.1.jar
    | |-...
    |_runme.bat

    Теперь, возможно старым java программистам будет интересно узнать, что в Java 6 наконец-то в classpath можно использовать звездочку (*).
    Раньше многие делали так:

    set CP=lib/mytools-1.0-SNAPSHOT-jar
    set CP=%CP%;lib/commons-lang-2.4.jar
    rem "и так до самого конца"
    java -cp %CP% com.programmisty.Main %*

    Те кто похитрее делал так:

    setlocal ENABLEDELAYEDEXPANSION
    set CP=
    for %%i in (lib/*.jar) do set CP=!CP!lib/%%i;
    java -cp %CP% com.programmisty.tools.Main %*

    Если вы работаете в Linux, то для настоящего линуксоида получить список jar-файлов в директории и присвоить значение переменной — задачка “школьного” уровня. По этой ссылке можно найти несколько способ ее решения http://www.sql.ru/Forum/actualthread.aspx?bid=38&tid=569498

    Но теперь, если у вас java 6 это вообще не проблема, файл runme.bat может выглядеть следующим образом:

    java -cp "lib/*" com.programmisty.tools.Main %*

    Под линуксом wildcard (то есть звездочка) также успешно работает. Подробнее можно прочитать здесь: http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html в разделе “Understanding class path wildcards”

  • Camel Case

    camel caseCamel Case, он же — Верблюжий Регистр, он же — Горбатый Стиль.

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

    Такой стиль используется в языке программирования  Java. Для названия классов используют UpperCamelCase (верблюд поднял голову – первая буква большая),  для методов и объектов класса — lowerCamelCase (верблюд опустил голову).

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

    Не будь верблюдом, не плюй на других, используй верблюжий регистр!

    Пожалуйста, соблюдайте доброжелательное отношение к другим людям!

  • Hibernate. Update. Популярные грабли

    hibernate
    Сейчас многие любят реализовывать Data Access Object (DAO) на базе Hibernate.
    Хотелось уделить особое внимание работе с объектами в различных состояниях.
    Пример из документации :

       DomesticCat cat = (DomesticCat) sess.load( Cat.class, new Long(69) );
       cat.setName("PK");
       sess.flush();  // changes to cat are automatically detected and persisted
    

    Некоторые думают, что нужно делать так:

       DomesticCat cat = (DomesticCat) sess.load( Cat.class, new Long(69) );
       cat.setName("PK");
       sess.update(cat); // НЕ НАДО, ОНО САМО СОХРАНИТСЯ !!!! REMOVE THIS LINE
       sess.flush();  // changes to cat are automatically detected and persisted
    

    (далее…)

  • мини-справочник по PKCS-ам

    Мой мини-справочник по PKCS-ам:

    PKCS#7 – Подпись и сертификаты  (Cryptographic Message Syntax Standard)

    PKCS#8 – Секретные ключи

    PKCS#10 – Запрос к УЦ на выпуск сертификата (Certification Request Standard)

    PKCS#11 – API для криптотокенов

    PKCS#12 – Хранилище секретных  ключей и сертификатов (Personal Information Exchange Syntax Standard)

    Как работать с подписью, ключами и сертификатами  в Java можно прочитать в официальном туториале

    Если лень, то готовые примеры можно взять на java2s.com

  • Как программисты видят друг друга. Java, C, PHP, Ruby, Haskell

    Как программисты видят друг друга:

    как программисты видят друг друга

    Авторство, к сожалению, определить не смог, картинка сильно разошлась в интернете. Изначально, наткнулся на подобную картинку в комментариях к посту в блоге Алены С++ про программистов различных специальностей.  Еще интересная картинка,  которая меня порадовала как бывшего LISP-программиста: (далее…)

  • Как считается TIOBE индекс?

    Прочитал новость на слэшдоте о новых данных по TIOBE индексу языков программирования за Апрель 2010 года (оригинальную статью можно прочитать здесь):

    Position
    Apr 2010
    Position
    Apr 2009
    Delta in Position Programming Language Ratings
    Apr 2010
    Delta
    Apr 2009
    Status
    1 2 C 18.058% +2.59% A
    2 1 Java 18.051% -1.29% A
    3 3 C++ 9.707% -1.03% A
    4 4 PHP 9.662% -0.23% A

    В итоге, разница в индексе популярности языков программирования (по методике TIOBE) между С и Java составляет около 0.007, что на мой взгляд незначительно (по сравнению Java – PHP = 8.389)

    Индекс считается очень интересно. (далее…)

  • Учебное пособие по Scala. Вольный перевод.

    В связи с малым количеством (на момент публикации этого поста) полноценных учебных материалов по языку программирования Scala на русском языке , постарался сделать простой перевод краткого пособия.
    Оригинальная статья лежит здесь http://www.scala-lang.org/docu/files/ScalaTutorial.pdf
    Корректура текста будет осуществляться после публикации, по ходу получения отзывов, комментариев и повторной вычитки. Возможно, через некоторое время выложу PDF-версию.

    Scala Tutorial.

    Авторы: Michel Schinz, Philipp Haller. Версия 1.3. 15 марта, 2009

    Учебное пособие по Scala. Вольный перевод.

    Автор перевода: Вит. 30 марта 2010.

    Введение

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

    Первый пример

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

    object HelloWorld {
        def main(args: Array[String]) {
            println("Hello, world!")
        }
    }
    

    Структура такой программы должна быть знакома Java-программистам. Она состоит из main-метода, который получает аргументы командной строки в виде массива строк в качестве параметров. Тело метода состоит из единственного метода println, в качестве аргумента которому передаётся «Hello, World!». Метод main ничего не возвращает, поэтому нет необходимости явно указывать тип возвращаемых данных.

    Java программиста может смутить в самом начале слово object в котором содержится main метод. (далее…)