Proszę rozważyć następujący przykład:Co decyduje, który interfejs funkcjonalny utworzyć z lambda?
import java.util.function.Consumer;
public class Example {
public static void main(String[] args) {
Example example = new Example();
example.setConsumer(test -> System.out.println("passed string is " + test)); //uses MyConsumer, why ?
example.getConsumer().accept("Test 1");
example.setConsumer((MyConsumer<String>)test -> System.out.println("passed string is " + test)); //uses MyConsumer
example.getConsumer().accept("Test 2");
example.setConsumer((Consumer<String>)test -> System.out.println("passed string is " + test)); //uses Consumer
example.getConsumer().accept("Test 3");
}
private Consumer<String> consumer;
public Consumer<String> getConsumer() {
return consumer;
}
public void setConsumer(Consumer<String> consumer) {
this.consumer = consumer;
}
public void setConsumer(MyConsumer<String> consumer) {
this.consumer = consumer;
}
@FunctionalInterface
public interface MyConsumer<T> extends Consumer<T> {
@Override
default void accept(T value) {
System.out.println("In consumer string: " + value); //example thing to do
receive(value);
}
void receive(T value);
}
}
Co tu interesuje mnie to pierwsza próba. Dlaczego korzysta z MyConsumer zamiast z Consumer? Co jeśli miałbym więcej różnych Konsumentów o tej samej strukturze lambda, kto ma pierwszeństwo? Dodatkowo obsada, którą wykonuję w teście 2, jest oznaczona jako IDprzez moje IDE. Oznacza to, że lamdba jest najpierw tworzona jako MyConsumer. Dlaczego tak ?
Używam IntelliJ IDEA z javac.
Nie wiem, którego IDE używasz. Myślę, że to JVM, używając typu środowiska wykonawczego obiektu, "decyduje". – duffymo
Myślę, że Java wybiera najbardziej specyficzny typ, który w tym przypadku jest "MyConsumer". Jeśli 'MyConsumer' nie byłby podinterfejsem' Consumer', myślę, że dostałeśby błąd, mówiąc, że jest to połączenie ambiwalentne. – marstran
Wybiera najbardziej szczegółową metodę. Gdyby na przykład 'MyConsumer2 rozszerzył Konsumenta ' i 'setConsumer (MyConsumer2 konsumenta), wówczas pierwsze wywołanie byłoby niejednoznaczne i wystąpiłby błąd czasu kompilacji. Zobacz także [JLS 15.12.2.5] (https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.5). –