Вызвать параметризованный конструктор в перечислении singleton?

#java #enums

#java #перечисления

Вопрос:

У меня есть этот класс перечисления singleton:

 enum C1 {
    INSTANCE("");

    C1(String s) {
        System.out.println("with param = "  s);
    }
    C1() {
        System.out.println("without param");
    }   
    public void g() {
        System.out.println("inside g");
    }
}

public class Main {
    public static void main(String s[]) {
        C1.INSTANCE.g();
        C1.INSTANCE.g();

    }
}
  

Как я могу вызвать C1(String s) конструктор с помощью INSTANCE , передав пользовательский параметр?

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

1. Вы уже вызываете конструктор, который принимает строку.

2. Вы не можете вручную вызвать конструктор enum. Это выполняется автоматически при создании констант перечисления.

3. INSTANCE создается ли статический экземпляр с использованием какого-либо конструктора (в вашем случае C1(String s) ). Вы не можете вызвать конструктор для уже созданного объекта. В чем реальная проблема, стоящая за этим вопросом?

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

5. INSTANCE("hello") создает статический экземпляр, и вы не можете повторно инициализировать его. Вы можете добавить параметр в g() функцию. В чем реальная проблема, стоящая за этим вопросом?

Ответ №1:

У вас может быть что-то подобное

     enum C1 {
        WITH_PARAM("value"),
        EMPTY();

        private String value;
        C1(String s) {
            System.out.println("with param = "  s);
            value=s;
        }
        C1() {
            System.out.println("without param");
        }
        public void g() {
            System.out.println("inside g, value is " value);
        }
    }

        public static void main(String s[]) {
            C1.EMPTY.g();
            C1.WITH_PARAM.g();

        }
  

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

1. Могу ли я отправлять параметры динамически??

2. В конструктор? Он создает singleton, чтобы вы могли отправлять параметры, но только один раз. Например, вы можете инициализировать с помощью переменной окружения, чтобы в какой-то степени это было «динамически»

Ответ №2:

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

 public enum Vehicle {
    CAR(4, 2),
    TRUCK(6, 20);

    private Integer numOfTyres;
    private Integer maxWeight;

    Vehicle(Integer numOfTyres, Integer maxWeight) {
        this.numOfTyres = numOfTyres;
        this.maxWeight = maxWeight;
        System.out.println("Number of Tyres = "   numOfTyres);
        System.out.println("Max weight = "   maxWeight);
    }


    public Integer getMaxWeight() {
         return maxWeight;
    }

    public Integer getNumberOfTyres() {
        return numOfTyres;
    }

}


public class Main {
    public static void main(String s[]) {
        Vehicle.CAR.getNumberOfTyres();

        for (Vehicle v : Vehicle.values()) {
            System.out.println();

            StringBuilder sb = new StringBuilder();
            sb.append("Vehicle ");
            sb.append(v.name());
            sb.append(" has ");
            sb.append(v.getNumberOfTyres());
            sb.append(" number of tyres and ");
            sb.append(v.getMaxWeight());
            sb.append(" max weight ");


            System.out.println("-----------------");
            System.out.println(sb.toString());
            System.out.println("-----------------");
        }

    }

}
  

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

1. Экземпляр enum является экземпляром класса. Фактически, эффективная Java предлагает использовать enum в качестве предпочтительного способа реализации одиночных элементов. Несколько конструкторов в OP, конечно, не имеют смысла в этом случае.

Ответ №3:

Как вы, вероятно, знаете, конструктор для перечисляемого типа должен быть package-private или с частным доступом.

Он вызывается автоматически и создает константы, которые определены в начале тела перечисления.

Вы не можете вызвать конструктор enum самостоятельно.

Вот несколько примеров, которые могут быть полезны.

 public enum MySingleton {
    // if you have multiple constants here - it's not Singleton
    INSTANCE;

    // if you need to provide some info to your INSTANCE,
    // you can add params to its methods
    public void someMethod(String value) {
        System.out.println("inside someMethod, value is "  value);
    }
}
  

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

 public enum MySingleton {
    INSTANCE("Hello");

    private String message;

    MySingleton(String msg) {
        this.message = msg;
    }

    // you can even have getter/setter for it
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
  

Пример основного метода:

 public static void main(String[] args) {
    System.out.println(MySingleton.INSTANCE.getMessage()); // prints Hello

    MySingleton.INSTANCE.setMessage("Bye");

    System.out.println(MySingleton .INSTANCE.getMessage()); // prints Bye
}