воскресенье, 9 октября 2011 г.

Comparison of toString() helpers


Многие (если не все) библиотеки с полезными методами-утилитами предоставляют возможность автоматизировать рутинное кодирование таких стандартных методов как hashCode(), equals() и toString(). В этой заметке приведены примеры метода toString(), которые созданы с помощью библиотек Google Guava, Apache Commons и Lombok.

Давайте создадим простенький класс, который в дальнейшем будем использовать в примерах:
public class Language {
private int id;
private String name;
private String locale;
public Language(final int id, final String name, final String locale) {
this.id = id;
this.name = name;
this.locale = locale;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getLocale() {
return locale;
}
public static void main(String [] args) {
System.out.println(new Language(1, "Russian", "ru_RU"));
}
}
view raw Language.java hosted with ❤ by GitHub

Если сейчас его скомпилировать и запустить, то на консоль будет выведена примерно следующая строчка:
Language@19f953d
Это пример вывода Object.toString(), который просто выводит название класса и его хэш код.

Lombok


Я уже писал о проекте Lombok, который занимается генерацией методов на основе аннотаций. В этот раз приведу пример использования @ToString:
import lombok.ToString;
@ToString
public class Language {
...
}

Да, это всё! Достаточно лишь одной аннотации! Как вы увидите позже, это самый компактный из всех приведённых в этом обзоре способов. Кроме того, не забывайте, что в отличие от прочих библиотек Lombok необходим только на стадии компиляции.

Вот что теперь выведет наша программа:
Language(id=1, name=Russian, locale=ru_RU)

Google Guava


Следующим претендентом у нас будет Guava. Здесь уже необходимо немного больше ручного вмешательства:
import com.google.common.base.Objects;
public class Language {
...
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("id", getId())
.add("name", getName())
.add("locale", getLocale())
.toString();
}
}

Метод Objects.toStringHelper() принимает в качестве аргумента название класса. В случае передачи this будет использовано простое имя класса. Результат получился практически идентичным тому, что нагенерил мне Lombok, разве что скобки фигурные:
Language{id=1, name=Russian, locale=ru_RU}

Apache Commons


И последним в списке мы попробуем commons-lang, а именно класс ToStringBuilder:
import org.apache.commons.lang.builder.ToStringBuilder;
public class Language {
...
@Override
public String toString() {
return new ToStringBuilder(this)
.append("id", getId())
.append("name", getName())
.append("locale", getLocale())
.toString();
}
}

Код очень похож на пример с Guava, потому что оба используют паттерн Builder.
Результаты же немного различаются:
Language@93dcd[id=1,name=Russian,locale=ru_RU]
Здесь бы уже и закончить, но разработчики этой библиотеки решили угодить всем и сразу: они позволили кастомизировать стиль отображения! Причем, заранее предоставили нам 5 готовых. Для того, чтобы использовать конкретный стиль, передайте его в конструктор ToStringBuilder вторым аргументом. Доступны следующие стили:

ToStringStyle.DEFAULT_STYLE Language@93dcd[id=1,name=Russian,locale=ru_RU]
ToStringStyle.MULTI_LINE_STYLE
Language@93dcd[
  id=1
  name=Russian
  locale=ru_RU
]
ToStringStyle.NO_FIELD_NAMES_STYLE Language@93dcd[1,Russian,ru_RU]
ToStringStyle.SHORT_PREFIX_STYLE Language[id=1,name=Russian,locale=ru_RU]
ToStringStyle.SIMPLE_STYLE 1,Russian,ru_RU

Кроме того, есть возможность взять любой из них и «подогнать» его под себя путём переопределения необходимых методов.

Комментариев нет:

Отправить комментарий