-1

In my enum constructor, I'm trying to initialize their members. I need to use a switch statement to know which enum is currently being instantiated. However for some reason this seems to return null which makes little sense to me. Is this null until the constructor completes? If so, how can I differentiate which enum is being constructed at run time? The example below is a simplified version of my actual code to demonstrate the problem.

Food f = Food.APPLE;
System.out.println(f.getTastes());

Food Enum

public enum Food
{
    APPLE,
    PANCAKES,
    PASTA;

    private List<String> tastes = new ArrayList<>();

    Food()
    {
        switch(this)
        {
        case APPLE:
            tastes.add("Sour");
            tastes.add("Sweet");
            break;
        case PANCAKES:
            tastes.add("Dough-y");
            break;
        case PASTA:
            tastes.add("Creamy");
            tastes.add("Rich");
            tastes.add("Velvet");
        }
    }

    public List<String> getTastes()
    {
        return tastes;
    }
}

I get the following exception

Exception in thread "main" java.lang.ExceptionInInitializerError
    at Food.<init>(Food.java:18)
    at Food.<clinit>(Food.java:10)
    at Tester.main(Tester.java:9)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.NullPointerException
    at Food.values(Food.java:8)
    at Food$1.<clinit>(Food.java:18)
    ... 8 more
Hatefiend
  • 3,416
  • 6
  • 33
  • 74
  • 5
    This is quite a roundabout way of differentiating your enum values - you should pass these in as parameters to the constructor. – Oliver Charlesworth Dec 06 '17 at 09:02
  • 1
    The constructor has to be called to create the enum constants. So you can't expect the enum constants to work inside the constructor. – khelwood Dec 06 '17 at 09:12

1 Answers1

4

I`m not sure if this would suit you, but i belive to be the correct pattern, instead of figuring out what taste each food have in constructor, you could just declare it.

public enum Food
{
  APPLE("good", "sweet"),
  PANCAKES("delicious","omg"),
  PASTA("too fat", "but its gud");

  private List<String> tastes = new ArrayList<>();

      Food(String ... tastes) {
        // add to the list
     }
  }
Gabriel Slomka
  • 1,487
  • 1
  • 11
  • 24
  • If you really want to add those tastes on a different place, i would suggest making another class that builds up the food enum object for you – Gabriel Slomka Dec 06 '17 at 09:09
  • To do this method, I would have to somehow initialize the enum in one line. That's not always possible (unless you make silly helper functions). I feel like this does not answer my question accurately. I know of correct enum instantiation but it does not explain the null pointer exception nor how to correct it in this fashion. – Hatefiend Dec 06 '17 at 09:23
  • @Hatefiend - Hopefully the duplicate question explains where the NPE comes from? – Oliver Charlesworth Dec 06 '17 at 09:26
  • `tastes` should be immutable in this case. Better use `List.of()` in constructor, for example. – gil.fernandes Dec 06 '17 at 09:30