Try to understand the usage of functions in a Java enum

Viewed 73

Here it's my question, why enums require a static/interface access to methods of a referenced class to work?

Here my code example with an interface, it works I guess because it's an Interface so is not a direct reference to an object implementation:

public interface PredicateBuilder<T extends Comparable> {

Predicate generateGreaterThan(PredicateContent<T> predicateContent);
...
}

Then I can use it in the Enum like this:

public enum Condition {
   GREATER_THAN(PredicateBuilder::generateGreaterThan, ">"),
   ...
   public final String operator;
   public final BiFunction<PredicateBuilder, PredicateContent<?>, Predicate> predicate;

   private Condition(BiFunction<PredicateBuilder, PredicateContent<?>, Predicate> predicate, String operator) {
      this.operator = operator;
      this.predicate = predicate;
   }
}

In that scenario works perfect.

Then I tried the following:

@Component
public class SomeClass {
   public String someMethod(String param){
      return "Stuff";
   }
/* This works
*      public static String someMethod(String param){
*         return "Stuff";
*      }
*/

   public void applyStuff(TestEnum enum,String param){
       enum.action.apply(param)
   }
   public enum TestEnum{
      OPTION_1(SomeClass::someMethod);
      private Function<String,String> action;
      private TestEnum(Function<String,String> action){
          this.action = action;
      }
   }
}

At this point the IDE complains because requires an static access to the method, I changed to static methods and it works. So why this limitation? Its because Enums are static so they only can access static/reference methods?

1 Answers

So why this limitation? Its because Enums are static so they only can access static/reference methods?

No, it is because you are calling a method without instantiating an instance of the Class SomeClass. Which leads to the problem that

Non-static method cannot be referenced from a static context

For instance, the following would work:

public class SomeClass {

      public String someMethod(String param){
              return "Stuff";
      }
    }
    public enum TestEnum{
        OPTION_1(a -> new SomeClass().someMethod("something"));
        private Function<String,String> action;
        private TestEnum(Function<String,String> action){
            this.action = action;
        }
    }
  }

because we initiate an object of the Class SomeClass (i.e., new SomeClass()), and therefore we can use a non-static method.

If you add SomeClass::someMethod you are explicitly telling the compiler that you want the static method named someMethod from the class SomeClass.

Related