Вопрос по java, string – Совместное использование постоянных строк в Java во многих классах?

42

Error: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

как насчет статического класса со статическими методами, которые возвращают константные строки? Nadir Sampaoli
Это не рекомендуемый метод проектирования для Java. Поместите свои константы в классы, где они актуальны. beerbajay
@beerbajay Но мне нужны эти строки в нескольких классах, каков рекомендуемый способ сделать это? Danijel
@Danijel, вы все равно сможете использовать их в разных классах, если вы сделаете это так, как советует beerbajay. Просто сделайте поля статичными, публичными и окончательными. toniedzwiedz
Это зависит от вашего конкретного варианта использования. Обычно существует один логический «мастер» расположение такой информации, поэтому вы помещаете туда константы, а затем ссылаетесь на этот класс и константу (например,MyClass.MY_CONSTANT) из других мест вам нужна информация. Если вам нужен «класс констант», это, как правило, указывает на то, что дизайн не был полностью продуман. beerbajay

Ваш Ответ

10   ответов
20

Как и раньше отвечал @mprabhat, константы должны бытьpublic, static, finalи набран заглавными буквами.

Группировка их в классе поможет вам:

  1. Don't need to know all the constants you have. Many IDEs (like Eclipse) show you the list of all the fields a class has. So you only press CTRL+SPACE and get a clue of which constants you can use.

  2. Making them typesafe at compile time. If you used Strings, you might misspell "DATABASE_EXCEPTION" with "DATABSE_EXSCEPTION", and only notice during execution (if you are lucky and notice it at all). You can also take profit of autocompletion.

  3. Helping you save memory during execution. You'll only need memory for 1 instance of the constant. I.E: (a real example) If you have the String "DATABASE_EXCEPTION" 1000 times in different classes in you code, each one of them will be a different instace in memory.

Некоторые другие соображения, которые вы могли бы иметь:

  1. Add javadoc comments, so programmers who use the constants can have more semantic information on the constant. It is showed as a tooltip when you press CTRL+SPACE. I.E:

    /** Indicates an exception during data retrieving, not during connection. */
    public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION";
    /** Indicates an exception during the connection to a database. */
    public static final String DATABASE_CONNECTION_EXCEPTION =" DATABASE_CONNECTION_EXCEPTION";
    
  2. Add semantic to the identifier of the constant. If you have the constant "Y", and sometimes means yes and other times year, consider using 2 different constants.

    public static final String Y = "Y"; // Bad
    public static final String YEAR = "Y";
    public static final String YES = "Y"; 
    

    It will help you if, in the future, decide to change the values of the constants.

    /** Year symbol, used for date formatters. */
    public static final String YEAR = "A"; // Year is Año, in Spanish.
    public static final String YES = "S"; // Yes is Sí, in Spanish.
    
  3. You might not know the value of your constants until runtime. IE: You can read them from configuration files.

    public class Constants
    {
      /** Message to be shown to the user if there's any SQL query problem. */
      public static final String DATABASE_EXCEPTION_MESSAGE; // Made with the 2 following ones.
      public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION";
      public static final String MESSAGE = "MESSAGE";
    
      static {
        DATABASE_EXCEPTION_MESSAGE = DATABASE_EXCEPTION + MESSAGE; // It will be executed only once, during the class's [first] instantiation.
      }
    

    }

  4. If your constants class is too large, or you presume it'll grow too much in the future, you can divide it in different classes for different meanings (again, semantic): ConstantDB, ConstantNetwork, etc.

Недостатки:

  1. All the members of your team have to use the same class(es), and the same nomenclature for the constants. In a large project it wouldn't be strange to find 2 definitions:

    public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION";
    public static final String EXCEPTION_DATABASE = "DATABASE_EXCEPTION"; 
    

    separated several hundreds of lines or in different constant classes. Or even worse:

    /** Indicates an exception during data retrieving, not during connection. */
    public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION";
    /** Indicates an exception during data retrieving, not during connection. */
    public static final String EXCEPTION_DATABASE = "EXCEPTION_DATABASE"; 
    

    different identifiers, for different values, having the same meaning (and used for the same purposes).

  2. It might make readability worse. Having to write more for doing the same:

    if ("Y".equals(getOptionSelected()) {
    

    vs

    if (ConstantsWebForm.YES.equals(getOptionSeleted()) {
    
  3. How should constants be ordered in the class? Alphabetically? All related constants together? In order as they are created/needed? Who sould be responsible of the order being correct? Any (big enough) reordering of constants would be seen as a mess in a versioning system.

Ну, это заняло больше времени, чем я ожидал. Любая помощь / критика приветствуется.

Отличный пост, спасибо. Danijel
Спасибо за поддержку.
Спасибо за подробности! +1
7

Лучшая практика заключается в использовании Java Enum (после Java 5)

Проблемы с классовым подходом:

  1. Not typesafe
  2. No namespace
  3. Brittleness

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

public enum Constants {

    CONSTANT_STRING1("CONSTANT_VALUE1"), 
    CONSTANT_STRING2("CONSTANT_VALUE2"), 
    CONSTANT_STRING3("CONSTANT_VALUE3");

    private String constants;

    private Constants(String cons) {
        this.constants = cons;
    }
}

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

Edit: Вы можете назвать этоConstants.CONSTANT_STRING1

Эти проблемы (типизированные, пространство имен и хрупкость) произошли со старымEnum подход (как шаблон, до Java 5). Увидетьenums at the JavaDoc
Способ назвать это не такConstants.CONSTANT_STRING1, поскольку он возвращает что-то типаConstants, Вы должны позвонитьConstants.CONSTANT_STRING1.toString() или жеConstants.CONSTANT_STRING1.name().
Как J.A.I.L. прокомментировал, ваш текущий пример кодаnot Работа. Ваш звонок возвращает объект типаConstants а неString по желанию в вопросе.
3
public class SomeClass {
    public static final String MY_CONST = "Some Value";
}

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

public class Constants {
    public static final String CONST_1 = "Value 1";
    public static final int CONST_2 = 754;

    private Constants() {
    }
}

Тогда не будет возможности создать экземпляр этого класса.

@Ryuji Вы совершенно не правы, и вы смешиваете это с C #. Посмотрите здесь, например:stackoverflow.com/a/7486111/1350762
Лучше просто сделать этоstaticВы не должны использовать этот "приватный конструктор" подход, когда есть лучшие варианты, встроенные в Java.
0

Создать общедоступныйclass и для каждой постоянной строки создайте поле, подобное этому

public static final String variableName = "string value";

17

Вы должны создать класс констант, который хранит все константы.

как ProjectNameConstants.java

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

например

classname :  MyAppConstants.java

public static final String MY_CONST="my const string val";

вы можете получить к нему доступ как

MyAppConstants.MY_CONST
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
2

Создайте класс с именемConstants в основе вашего основного пакета (то есть com.yourcompany) со всеми вашими константами там. Также сделайте конструктор приватным, чтобы из этого класса не было создано никаких объектов:

public class Constants {

    private Constants() {
        // No need to create Constants objects
    }

    public static final String CONSTANT_ONE = "VALUE_CONSTANT_ONE";
    public static final String CONSTANT_TWO = "VALUE_CONSTANT_TWO";
}
42
public static final String CONSTANT_STRING="CONSTANT_STRING";

константы должны быть:

  1. public - so that it can be accessed from anywhere
  2. static - no need to create an instance
  3. final - since its constants shouldnt be allowed to change
  4. As per Java naming convention should be capitalized so that easy to read and stands out in Java documentation.

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

например,

JFrame имеетEXIT_ON_CLOSE Контант, любой класс, который подклассыJFrame будет иметь доступ к нему, и это также имеет смысл держать вJFrame и не вJComponent поскольку не все компоненты будут иметь возможность быть закрытыми.

@Jimmy: почему использование интерфейсов - плохая практика?
интерфейсы контрактные, используя их только для хранения констант, не имеет смысла
@WickeD использование интерфейса - неплохая практика, но использование интерфейса для хранения констант :) пожалуйста, прочитайте эту ссылку для более подробного объяснения:stackoverflow.com/questions/320588/…
Является ли все еще плохой практикой создание интерфейса или класса, содержащего константы, если они применяются ко всем классам в пакете, но не ко всем конкретно? Например, строка префикса сообщения журнала.
+1 за хороший ответ. Использование интерфейса для этой цели считается плохой практикой, о которой следует упомянуть.
0
public enum Constants {

CONSTANT_STRING1("CONSTANT_VALUE1"), 
CONSTANT_STRING2("CONSTANT_VALUE2"), 
CONSTANT_STRING3("CONSTANT_VALUE3");

private String constants;

private Constants(String cons) {
    this.constants = cons;
}
    @JsonValue
@Override
public String toString() {
    return constants;
}

}

Используйте это Constants.CONSTANT_STRING1.toString ()

-1

Я думаю, правильный ответ, который вы ищете,

import static com.package.YourConstantsClass.*;
Отрицательный рейтинг? Так вы импортируете свои константы в другие классы.
1

Вы должны разбить ваши константы на группы, к которым они принадлежат, например, там, где они будут использоваться чаще всего, и определить их как public static final в этих классах. По мере продвижения, может показаться уместным иметь интерфейсы, которые определяют ваши константы, но противостоят желанию создать один монолитный интерфейс, который содержит все константы. Это просто не очень хороший дизайн.

Похожие вопросы