Подтвердить что ты не робот

Как вы определяете класс констант в Java?

Предположим, вам нужно определить класс, который все это делает, это постоянные.

public static final String SOME_CONST = "SOME_VALUE";

Каков предпочтительный способ сделать это?

  • Интерфейс
  • Абстрактный класс
  • Конечный класс

Какой я должен использовать и почему?


Пояснения к некоторым ответам:

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

Интерфейс. Я не собираюсь устанавливать какой-либо класс как тот, который реализует интерфейс. Просто хочу использовать интерфейс для вызова констант: ISomeInterface.SOME_CONST.

4b9b3361

Ответ 1

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

public final class MyValues {
  public static final String VALUE1 = "foo";
  public static final String VALUE2 = "bar";
}

в другом классе:

import static MyValues.*
//...

if(variable.equals(VALUE1)){
//...
}

Ответ 2

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

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

Ответ 3

Мои предложения (в порядке убывания предпочтения):

1) Не делайте этого. Создайте константы в фактическом классе, где они наиболее важны. Наличие класса "мешок констант" /интерфейса не соответствует рекомендациям OO.

Я, и все остальные, время от времени игнорируем # 1. Если вы собираетесь это сделать, то:

2) конечный класс с частным конструктором. Это, по крайней мере, предотвратит любое злоупотребление вашей "сумкой констант", расширяя/внедряя его, чтобы получить легкий доступ к константам. (Я знаю, вы сказали, что не сделаете этого, но это не значит, что кто-то идет вперед, когда вы этого не сделаете)

3) интерфейс. Это будет работать, но не мое предпочтение, дающее возможное упоминание о злоупотреблении в # 2.

В общем, только потому, что это константы, это не значит, что вы не должны применять к ним нормальные принципы оо. Если никто, кроме класса, не заботится о константе - он должен быть частным и в этом классе. Если только тесты заботятся о константе - она ​​должна быть в тестовом классе, а не в производственном коде. Если константа определена в нескольких местах (а не просто случайно) - рефакторинг для устранения дублирования. И так далее - относитесь к ним так же, как к методу.

Ответ 4

Как отмечает Джошуа Блох в "Эффективной Java":

  • Интерфейсы должны использоваться только для определения типов,
  • абстрактные классы не предотвращают непредвиденности (они могут быть подклассифицированы и даже предполагают, что они предназначены для подкласса).

Вы можете использовать Enum, если все ваши константы связаны (например, имена планет), поместить постоянные значения в классы, к которым они относятся (если у вас есть к ним доступ), или использовать нежизнеспособный класс утилиты (определить частный конструктор по умолчанию).

class SomeConstants
{
    // Prevents instanciation of myself and my subclasses
    private SomeConstants() {}

    public final static String TOTO = "toto";
    public final static Integer TEN = 10;
    //...
}

Затем, как уже было сказано, вы можете использовать статический импорт для использования своих констант.

Ответ 5

Просто используйте конечный класс.

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

Это не имеет смысла с помощью интерфейса, интерфейс должен указывать контракт. Вы просто хотите объявить некоторые постоянные значения.

Ответ 6

Мой предпочтительный метод - это не делать этого вообще. Возраст констант в значительной степени скончался, когда Java 5 ввела типичные перечисления. И еще до этого Джош Блох опубликовал (немного более многословную) версию этого, которая работала над Java 1.4 (и ранее).

Если вам не нужна совместимость с каким-либо унаследованным кодом, на самом деле нет причин использовать константы с именем String/integer.

Ответ 7

enum в порядке. IIRC, один элемент в эффективной Java (2-е изд.) Имеет константы enum, перечисляющие стандартные опции, реализующие [ключевое слово Java] interface для любого значения.

Мое предпочтение заключается в использовании ключевого слова [Java ключевое слово] interface над a final class для констант. Вы неявно получаете public static final. Некоторые люди утверждают, что interface позволяет плохим программистам реализовать его, но плохие программисты собираются писать код, который отстой независимо от того, что вы делаете.

Что выглядит лучше?

public final class SomeStuff {
     private SomeStuff() {
         throw new Error();
     }
     public static final String SOME_CONST = "Some value or another, I don't know.";
}

Или:

public interface SomeStuff {
     String SOME_CONST = "Some value or another, I don't know.";
}

Ответ 8

Не enums лучший выбор для такого рода вещей?

Ответ 9

Или 4. Поместите их в класс, который содержит логику, которая использует константы наиболее

... извините, не смог устоять; -)

Ответ 10

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

  • Перечисление по понятию природы хорошо применимо в конкретном типе домена, применять его к децентрализованным константам выглядит недостаточно хорошо

Понятие Enum - "Перечисления - это совокупности тесно связанных элементов".

  1. Расширение/реализация постоянного интерфейса - это плохая практика, трудно думать о необходимости расширения неизменяемой константы, а не прямого обращения к ней.

  2. Если применить качественный инструмент, такой как SonarSource, существуют правила, которые заставляют разработчика отказаться от постоянного интерфейса, это неудобно, поскольку многие проекты пользуются постоянным интерфейсом и редко видят, что "расширение" происходит на постоянных интерфейсах