Cannot make a static reference to the non-static field memberVariable with private variable

前端 未结 3 878
一生所求
一生所求 2020-12-31 02:30

I created a enum with one private member variable. When i try to access the member variable the compiles states \'Cannot make a static reference to the non-static field memb

相关标签:
3条回答
  • 2020-12-31 02:40

    The error message is confusing.

    The problem is that when you give an enum value code, you are creating an anonymous sub class of the enum. (Its class will be EnumWithAbstractMethodAndMembers$1) A sub-class cannot access the private members of its super-class, however nested classes can via generated accessor method. You should be able to access the private field, and the error message it gives you appears to be mis-leading.

    BTW You can use this, but you shouldn't need to IMHO.

        public int addValue(final int value) {
            return super.memberVariable + value;
        }
    

    Here is a shorter example I will log as a bug in the error message as it doesn't lead to a solution to the problem.

    public enum MyEnum {
        One {
            public int getMemberVariableFailes() {
                // error: non-static variable memberVariable cannot be referenced from a static context
                return memberVariable;
            }
    
            public int getMemberVariable2OK() {
                return memberVariable2;
            }
    
            public int getMemberVariableOK() {
                return super.memberVariable;
            }
        };
    
        private final int memberVariable = 1;
        final int memberVariable2 = 1;
    }
    

    Based on Tom Hawkin's feedback, this example gets the same error message.

    public class MyNotEnum {
        // this is the static context in which the anonymous is created
        public static final MyNotEnum One = new MyNotEnum() {
            public int getMemberVariableFailes() {
                // error: non-static variable memberVariable cannot be referenced from a static context
                return memberVariable;
            }
    
            public int getMemberVariableOK() {
                return super.memberVariable;
            }
        };
        private final int memberVariable = 1;
    }
    

    for comparison

    public class MyNotEnum {
        public class NestedNotEnum extends MyNotEnum {
            public int getMemberVariableFailes() {
                // compiles just fine.
                return memberVariable;
            }
    
            public int getMemberVariableOK() {
                return super.memberVariable;
            }
        }
        private final int memberVariable = 1;
    }
    
    0 讨论(0)
  • 2020-12-31 02:53

    The main cause of error is : you are trying to make reference to private variable (memberVariable) of super class from inner implementation class.

    To make error free code you can do either of following :

    • you have to use super.memberVariable since memberVariable is not local to TheOnlyAndOnly()
    • you can make int memberVariable public.
    • you can do:

      TheOneAndOnly(1) {
          int memberVariable=4;
          @Override
          public int addValue(final int value) {
              return memberVariable + value;
          }
      };
      
    0 讨论(0)
  • 2020-12-31 02:55

    A similar issue is covered by Puzzle 92 (Twisted Pair) in Java Puzzlers by Josh Bloch and Neal Gafter.

    It's nothing special about enums. Any anonymous (or local) inner class in a static context will do. The rules are that the outer class is considered before the super class. This makes a lot of sense for such classes in a non-static context. If changing the context to static changed which variable was looked up, the is the potential to introduce "confusion" at runtime (C++ is much more aggressive with this kind of rule).

    An inner class that extends an outer class has access to the private instance fields of the outer class, whether through this or some other instance.

    As we are allowed access, we need to somehow specify we want to go through the inner this rather than outer this. As Peter Lawrey points out super.member will do. You can also select the inner this, and then use that expression:

            return ((EnumWithAbstractMethodAndMembers)this).memberVariable + value;
    

    Or

            EnumWithAbstractMethodAndMembers innerThis = this;
            return innerThis.memberVariable + value;
    
    0 讨论(0)
提交回复
热议问题