Вопрос

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

public class MyClass
{
    private static final String KEYS = "ABC";
    private static final String[] DATA = {"AAA", "BBB", "CCC"};
    private static HashMap<Character, String> myMap;

    private MyClass() {
        System.out.println("Running constructor");
        populateMyMap();
    }

    private static void populateMyMap() {
        myMap = new HashMap<Character, String>();
        for (int i=0; i < KEYS.length; i++) {
            myMap.put(KEYS.charAt(i), DATA[i]);
        }
    }

    //various static methods
}

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

Извините, если это дубликат; Я пытался искать ответы, но я не уверен, что искать!

Это было полезно?

Решение

Статический блок инициализатора упоминался в нескольких других ответах. Но практически я нахожу следующую идиому чаще в дикой природе:

public class MyClass
{
    private static HashMap<Character, String> myMap = createMyMap();

    private static HashMap<Character, String> createMyMap() {
        HashMap<Character, String> myTmpMap = new HashMap<Character, String>();
        for (int i=0; i < KEYS.length; i++) {
            myTmpMap.put(KEYS.charAt(i), DATA[i]);
        }
        return myTmpMap;
    }
}

Другие советы

Нет, частный конструктор - это не то, что вы хотите. Конструктор инициализирует пример вашего класса (когда вы звоните new MyClass()), но статическое состояние не принадлежит экземпляру и не должно быть инициализировано из конструктора. Инициализация, которую вы хотите произойти, когда класс сначала загружен в static Блок размещен на уровне класса.

static {
   populateMyMap();
}

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

Подумайте о том, чтобы сделать вашу карту член экземпляра вашего класса вместо этого.

Используйте статический инициализатор:

public class MyClass
{
    static {
    //init
    }
}

Есть два способа достижения этого. Одним из них является то, чтобы сделать метод «Populatemimap» статическим инициализатором (или подходом, предложенным AH). Затем он гарантированно будет выполнен до первого статического вызова. Обычно это лучший способ, если предположить, что либо стоимость запуска Populatemimap достаточно мала, чтобы не быть замеченной, либо если вы собираетесь использовать функциональность класса почти каждый раз, когда приложение запускается.

Альтернативный подход - это то, что вы бы использовали, если бы запуск «populatemymap» - это то, что занимает значительное количество времени, и либо вы либо не можете использовать функциональность для некоторых выполнений приложения, либо вы хотите отложить выполнение Populatememap до тех пор, пока данные. необходимо, чтобы не излишне увеличить время запуска.

Если второй подход - это то, что вы хотите, вы должны переключать структуры и использовать синглтон, а не статические методы. Сделайте методы (и данные) нестатическими и попросите каждого пользователя из них получить экземпляр Singleton, прежде чем вызовать метод на нем. Есть «Populatemymap», называемый в (частном) конструкторе. Да, я знаю, у синглтонов плохая репутация, и люди всегда говорят: «Избегайте их, потому что это просто глобальные методы замаскированных», но статические методы также являются просто глобальными методами. Ты ничего не теряешь. И таким образом вы не оплачиваете стоимость выполнения Populatemimap до (или если вам не нужно.

Предупреждение: если ваши структуры данных не являются неизменными, то есть они могут быть изменены после того, как они инициализированы, то вам, вероятно, не следует использовать ни одну из этих структур.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top