Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Store references to instance methods in a static context

Tags:

java

java-8

I would like to have a static map where the values are instance methods. Someting like:

public class MyClass {
    static Map<MyEnum, Consumer<String>> methodMapping;
    static {
        methodMapping = new EnumMap<>(MyEnum.class);

        methodMapping.put(MyEnum.FIRST, MyClass::firstMethod);
        methodMapping.put(MyEnum.SECOND, MyClass::secondMethod);
    }
    void firstMethod(String param) {
        ...
    }
    void secondMethod(String param) {
        ...
    }
}

This gives me an error saying "Non-static method cannot be referenced from a static context". I understand why this would be a problem if I would try to call the methods from the static context, but isn't it possible from an instance method to retrieve the method from the map and pass it this? Like:

MyClass.methodMapping.get(MyEnum.FIRST).accept(this, "string");

like image 918
Levi Avatar asked Apr 13 '26 18:04

Levi


2 Answers

This is solvable as easy as changing Consumer to BiConsumer, turning the receiver instance of MyClass to a parameter of the function:

public class MyClass {
    static Map<MyEnum, BiConsumer<MyClass,String>> methodMapping;
    static {
        methodMapping = new EnumMap<>(MyEnum.class);

        methodMapping.put(MyEnum.FIRST,  MyClass::firstMethod);
        methodMapping.put(MyEnum.SECOND, MyClass::secondMethod);
    }
    void firstMethod(String param) {
        ...
    }
    void secondMethod(String param) {
        ...
    }
    void callTheMethod(MyEnum e, String s) {
        methodMapping.get(e).accept(this, s);
    }
}
like image 196
Holger Avatar answered Apr 15 '26 09:04

Holger


You initialize methodMapping in a static initialization block. At that point, your instance methods can't be referred to yet because you haven't called new MyClass() yet.

You could fix this by either making your methods static, or moving the methodMapping initialization from the static block to a constructor.

PS: The keyword static can be omitted from the initialization block

like image 27
FrederikVH Avatar answered Apr 15 '26 08:04

FrederikVH