Why can't I create an enum in an inner class in Java?

JavaEnumsNestedInner Classes

Java Problem Overview


What I try to do is this:

public class History {
	public class State {
		public enum StateType {

Eclipse gives me this compile error on StateType: The member enum StateType must be defined inside a static member type.

The error disappears when I make the State class static. I could make State static, but I don't understand why I cannot declare an enum in an inner class.

Java Solutions


Solution 1 - Java

enum types that are defined as nested types are always implicitly static (see JLS §8.9. Enums)

You can't have a static nested type inside a non-static one (a.k.a an "inner class", see JLS §8.1.3. Inner Classes and Enclosing Instances).

Therefore you can't have an enum inner type inside a non-static nested type.

Solution 2 - Java

If you declared an enum like this:

enum Suit {SPADES, HEARTS, CLUBS, DIAMONDS}

The Java compiler would synthetically generate the following class for you:

final class Suit extends java.lang.Enum<Suit> {
  public static final Suit SPADES;
  public static final Suit HEARTS;
  public static final Suit CLUBS;
  public static final Suit DIAMONDS;
  private static final Suit[] $VALUES;
  public static Suit[] values();
  public static Suit valueOf(java.lang.String);
  private Suit();
}

There is no intention to create other instances of this class other than those static fields already defined in it (as you could infer from its private constructor), but most importantly, and as mentioned in the accepted answer, a inner class cannot have static members (JLS §8.1.3. Inner Classes and Enclosing Instances), and since the enum synthetic class does, it makes it unacceptable as inner class.

Solution 3 - Java

Already enough information from +Joachim Sauer, I am just adding some extra details.

You can define inner enum only if your inner class is static nested inner class. See below

private static class DbResource {
	
	public enum DB {
		MERGE_FROM, MERGE_TO, MAIN;
	}
}

Solution 4 - Java

This worked for my use-case:

public class History {

    public interface HConstants{
         public enum StateType { PAST,CURRENT,FUTURE}
    }

    //Inner class
    public class State implements HConstants{
        public StateType stateField = StateType.PAST;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSteven RooseView Question on Stackoverflow
Solution 1 - JavaJoachim SauerView Answer on Stackoverflow
Solution 2 - JavaEdwin DalorzoView Answer on Stackoverflow
Solution 3 - JavaDhiral PandyaView Answer on Stackoverflow
Solution 4 - JavaK FView Answer on Stackoverflow