моделирование статического класса в Java - PullRequest
2 голосов
/ 07 августа 2009

Что вы думаете о следующем способе моделирования статического класса в Java? Вы можете добавить нестатические методы, но не сможете их вызывать.

 /**
  * Utility class: this class contains only static methods and behaves as a static class.
  */
 // ... prevent instantiation with abstract keyword
 public abstract class Utilities
    {
        // ... prevent inheritance with private constructor
        private Utilities() {}

        // ... all your static methods here
        public static Person convert(String foo) {...}
    }

Ответы [ 7 ]

8 голосов
/ 07 августа 2009

Это обычный способ. Однако в ключевом слове abstract нет необходимости. Использование частного конструктора достаточно, потому что

  • предотвращает создание объектов (вне класса)
  • предотвращает наследование

Ключевое слово abstract подсказывает пользователю, что пользователи класса могут реализовать класс, что здесь не так.

5 голосов
/ 07 августа 2009

Элемент 4 в Эффективная Java (очень ... эффективная книга) говорит:

// Noninstantiable utility class
public final class Utility {

    private Utility() {
        throw new AssertionError();
    }
}

потому что явный конструктор является приватным:

  • вы не можете создать его экземпляр
  • вы не можете расширить его (как если бы оно было объявлено как окончательное)

AssertionError не требуется, но дает еще одно небольшое преимущество: он предотвращает случайное вызывание конструктора из класса.

Вы также можете создать специальную аннотацию, например @BagOfFunction, и аннотировать свой класс:

@BagOfFunctions
public final class Utility {

    private Utility() {
        throw new AssertionError();
    }
}

в основном вы торгуете комментарием для самодокументируемой аннотации.

3 голосов
/ 07 августа 2009

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

2 голосов
/ 07 августа 2009

Я должен согласиться с тем, что выше. Используйте «окончательный» вместо «абстрактный». Помните, что такие слова, как «конечный» и «абстрактный», являются не только средством общения с вашими коллегами-программистами, но и инструкциями для компьютера. Абстрактное подразумевает, что потом будут классы-потомки, тогда как окончательное окончательно означает, что вы, кроме рефакторинга, не увидите ничего, что происходит от этого класса (что и подразумевается).

Кроме того, в большинстве стандартов, которые я видел, и последовательно в моей компании считается наилучшей практикой делать абстрактный класс чем-то, что конкретно оставлено неиспользованным, за исключением родительских для других классов. «Абстрактный» трактуется как «проект» или «общая структура», вы никогда не будете водить «абстрактный» автомобиль. С другой стороны, конечные классы создаются постоянно, особенно с использованием шаблонов Factory.

2 голосов
/ 07 августа 2009

Я предпочитаю делать такие классы final, но не abstract. Хотя это вопрос личного стиля.

Кстати, я полагаю, что все еще можно вызывать методы его экземпляра, если вы вложите некоторые энергии. Например. можно попытаться использовать objenesis для создания экземпляра класса.

2 голосов
/ 07 августа 2009

я бы сказал, если вы уже имеете личный конструктор

частные утилиты () {}

абстрактное ключевое слово не обязательно. скорее сделайте это окончательным.

разница с вашей версией незначительна для любых практических средств.

1 голос
/ 07 августа 2009

Мое предложение: предотвратить неправильное использование (т.е. создание экземпляра) путем размещения javadocs

Разве это не проще? Я думаю, что ваши товарищи по команде умеют читать;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...