Почему переменным из enum присваиваются неверные значения

Имеется класс Food, в котором имеется перечисление Ration:

public class Food {
    private Ration  ration[] = Ration.values();       // Возвращаем массив, содержищий список констант типа Ration

public void getValue(){
        for(int i = 0; i < ration.length; i++) {
            System.out.println("Имя: " + ration[i].getName());
            System.out.println("Состояние: " + ration[i].getInclude() + "\n");
        }
    }

// Конструктор
    public Food(boolean breakfast, boolean lunch, boolean dinner, boolean supper, boolean alcohol){
        ration[0].setInclude(breakfast);
        ration[1].setInclude(lunch);
        ration[2].setInclude(dinner);
        ration[3].setInclude(supper);
        ration[4].setInclude(alcohol);
        setTotalCost();
    }
}

// Дневной рацион
enum Ration{
    // Завтрак
    BREAKFAST{
        String  name = "Завтрак";
        boolean include = false;
        int     cost    = 10;

        @Override
        public void setInclude(boolean value){
            include = value;
        }

        @Override
        public boolean getInclude() {
            return include;
        }

        @Override
        public int getCost(){
            return cost;
        }

        @Override
        public String getName(){
            return name;
        }
    },

    // Обед
    LUNCH{
        String  name = "Обед";
        boolean include = false;
        int     cost    = 11;

        @Override
        public void setInclude(boolean value){
            include = value;
        }

        @Override
        public boolean getInclude() {
            return include;
        }

        @Override
        public int getCost(){
            return cost;
        }

        @Override
        public String getName(){
            return name;
        }
    },

    // Ужин
    DINNER{
        String  name = "Ужин";
        boolean include = false;
        int     cost    = 12;

        @Override
        public void setInclude(boolean value){
            include = value;
        }

        @Override
        public boolean getInclude() {
            return include;
        }

        @Override
        public int getCost(){
            return cost;
        }

        @Override
        public String getName(){
            return name;
        }
    },

    // Прием пищи перед сном
    SUPPER{
        String  name = "Прием пищи перед сном";
        boolean include = false;
        int     cost    = 13;

        @Override
        public void setInclude(boolean value){
            include = value;
        }

        @Override
        public boolean getInclude() {
            return include;
        }

        @Override
        public int getCost(){
            return cost;
        }

        @Override
        public String getName(){
            return name;
        }
    },

    // Алкоголь
    ALCOHOL{
        String  name = "Алкоголь";
        boolean include = false;
        int     cost    = 14;

        @Override
        public void setInclude(boolean value){
            include = value;
        }

        @Override
        public boolean getInclude() {
            return include;
        }

        @Override
        public int getCost(){
            return cost;
        }

        @Override
        public String getName(){
            return name;
        }
    };

    public abstract void    setInclude(boolean value);  // включить в ассортимент
    public abstract boolean getInclude();               // получить состояние включения в ассортимент
    public abstract int     getCost();                  // получить стоимость отдельных пунктов рациона
    public abstract String  getName();                  // получить тип рациона
}

В классе Main создаю экземпляр класса Food:

        Food food0 = new Food(false, false, false, false, false);
        Food food1 = new Food(true, false, false, false, false);
        Food food2 = new Food(true, true, false, false, false);
        Food food3 = new Food(true, true, true, false, false);
        Food food4 = new Food(true, true, true, true, false);
        Food food5 = new Food(true, true, true, true, true);

Почему при вызове метода getValue() класса Food я получаю все true?

Имя: Завтрак
Состояние: true

Имя: Обед
Состояние: true

Имя: Ужин
Состояние: true

Имя: Прием пищи перед сном
Состояние: true

Имя: Алкоголь
Состояние: true

Ответ:

Нельзя создавать экземпляры enum.


Ответы (3 шт):

Автор решения: instahipsta282

Enum - абстрактный класс. Его объекты("завтрак", "обед", "ужин" и так далее) - final. Т.е. их значения после создания менять вы уже не можете. В вашем случае следует переписать ваш Enum как-то так:

public enum Ration {

BREAKFAST("Завтрак", false, 10), DINER("Обед", false, 20);

    private String name;
    private boolean include;
    private int cost;

    Kek(String name, boolean include, int cost) {
        this.name = name;
        this.include = include;
        this.cost = cost;
    }
//При необходимости добавить геттеры и сеттеры
}
→ Ссылка
Автор решения: Igor

Почему при вызове метода getValue() класса Food я получаю все true?

<телепатия>

Потому что после

Food food1 = new Food(true, false, false, false, false);

у Вас где-то есть код

new Food(true, true, true, true, true);

который Вы не показали.

</телепатия>

Все остальное понятно?


Вижу - непонятно.

Ration.getValue() возвращает массив одних и тех же объектов, сколько бы раз Вы этот метод ни вызывали. Изменив свойство любого из этих объектов, Вы увидите эти изменения во всех экземплярах Food.

→ Ссылка
Автор решения: Алексей Осецкий

Я скопировал ваш код, удалил метод setTotalCost(); поскольку его реализации не было. И создал класс Test с методом main, добавил в main следующий код

Food food = new Food(true,false,false,false,false);
food.getValue();

И получил корректный вывод Корректный вывод

Затем исправил метод main после поправки вопроса

Food food0 = new Food(false, false, false, false, false);
        Food food1 = new Food(true, false, false, false, false);
        Food food2 = new Food(true, true, false, false, false);
        Food food3 = new Food(true, true, true, false, false);
        Food food4 = new Food(true, true, true, true, false);
        Food food5 = new Food(true, true, true, true, true);
        food1.getValue();

И получил вывод такой, как указанно в вопросе, потому что все объекты food... ссылаются на разные массивы Ration ration[], но на один базовый объект, это можно увидеть в debug idea Корректный вывод

Судя по вод этой строке кода

 private Ration  ration[] = Ration.values();       // Возвращаем массив, содержищий список констант типа Ration 

Где мы не создаём новый экземпляр класса, а постоянно обращаемся к единственному экземпляру класса Ration поведение программы вполне закономерное

→ Ссылка