0

The line

associations.put("test1",B::setBeta);

below does not compile. I'm not clear why it won't work since B extends A. Is there a way to make this work? I'm trying to build a map of method references from an inheritance family.

import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;

public enum Test {
    ENUM0() {
        @Override
        public void init() {
            associations.put("test0",A::setAlpha);
        }
    },
    ENUM1() {
        @Override
        public void init() {
            associations.put("test1",B::setBeta);
        }
    };
    public abstract void init();

    Map<String, BiConsumer<? extends A, String>> associations = new HashMap<>();
}

class A {
    public String getAlpha() {
        return alpha;
    }
    public void setAlpha(String alpha) {
        this.alpha = alpha;
    }

    String alpha;
}

class B extends A {
    public String getBeta() {
        return beta;
    }
    public void setBeta(String beta) {
        this.beta = beta;
    }

    String beta;
}
KevinRethwisch
  • 237
  • 2
  • 13

1 Answers1

1

This seems like a curious case of type inference, explicitly tagging the expression resolves the compilation errors:

associations.put("test1", (BiConsumer<B, String>) B::setBeta);
Jorn Vernee
  • 31,735
  • 4
  • 76
  • 93
  • Awesome! I didn't think about using a cast in that context. – KevinRethwisch Sep 14 '16 at 04:49
  • But don’t be surprised that the type inference doesn’t handle this case—a `BiConsumer extends A, String>` is useless as there is no correct way to invoke its `accept` method… – Holger Sep 14 '16 at 15:01
  • Actually it does work. The first parameter is a method call returning the proper type because Java cannot declare the variable properly AFAICT. – KevinRethwisch Sep 16 '16 at 02:43