2

Why does this not compile, and (relatedly) why is it that CC cannot access what I would have thought (maybe I'm wrong) its own (private) member variable i, when AA and BB can indeed do so? How can CC access its own member variable?

Thank you.

enum TestEnum {
  AA(1000), BB(500), CC(100) {
    public int getI() {
      return i + 1;
    }
  };
  TestEnum(int i) {
    this.i = i;
  }

  private int i;
  public int getI() {
    return this.i;
  }
}

javac output:

TestEnum.java:6: error: non-static variable i cannot be referenced from a static context
                 public int getI() { return i + 1; }
                                            ^
1 error
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
JL_SO
  • 1,742
  • 1
  • 25
  • 38
  • why do you have `getI` twice? what's with the brackets around the first one ? the semicolon should come directly after `CC(100)` ... See: http://jdoodle.com/a/mQF – Nir Alfasi Feb 14 '18 at 17:10
  • 1
    i is private, and technically you're making a subtype, would be my guess. Try super.getI instead of i. – Louis Wasserman Feb 14 '18 at 17:14
  • That is probably the correct guess, but the output of of javac points to the fact that i is static, which does not makes sense at the moment. Another test could be making `i` `protected` instead of `private` – Luca Negrini Feb 14 '18 at 17:17

2 Answers2

3

Use super.getI() - 1 since you want to override the parent's method.

public enum TestEnum {
    AA(1000), BB(500), CC(100) {

        @Override
        public int getI() {
            return super.getI() - 1;
        }
    };

    private int i;

    TestEnum(int i) {
        this.i = i;
    }

    public int getI() {
        return this.i;
    }
}

Alternatively make the field protected to access it directly (return i - 1;) as @oleg cherednik suggests. However, I prefer the solution above.

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
1

You have two options: either do a protected field or call super.getId(). I prefer to do first one, it is easier to read. Note: think about enum body like parent class, and each constants like children, therefore your private field is not visible in children AA, BB, CC.

public enum TestEnum {
    AA(1000),
    BB(500),
    CC(100) {
        @Override
        public int getI() {
            return i + 1;
        }
    };

    protected final int i;

    TestEnum(int i) {
        this.i = i;
    }

    public int getI() {
        return i;
    }
}

P.S. It is preferable to have only final fields in the enum, because enum is like constant and should not have any variables.

Oleg Cherednik
  • 17,377
  • 4
  • 21
  • 35