8

私はJava 8の本を読んでいますが、私が再現したサンプルが付属しています:

@FunctionalInterface
public interface Action {
    public void perform();
}

実装者:

public final class ActionImpl implements Action {
    public ActionImpl() {
        System.out.println("constructor[ActionIMPL]");
    }

    @Override
    public void perform() {
        System.out.println("perform method is called..");
    }    
}

発信者:

public final class MethodReferences {

    private final Action action;

    public MethodReferences(Action action) {
        this.action = action;
    }

    public void execute() {
        System.out.println("execute->called");
        action.perform();
        System.out.println("execute->exist");
    }

    public static void main(String[] args) {
        MethodReferences clazz = new MethodReferences(new ActionImpl());
        clazz.execute();
    }
}

これが呼び出された場合、以下が出力に出力されます。

constructor[ActionIMPL]
execute->called
perform method is called..
execute->exist

すべて問題ありませんが、メソッド参照を使用すると、perform messageメソッドが出力されません! これはなぜですか、何か足りないのですか?

このコードを使用する場合:

MethodReferences clazz = new MethodReferences(() -> new ActionImpl());
clazz.execute();

またはこのコード:

final MethodReferences clazz = new MethodReferences(ActionImpl::new);

これは印刷されます:

execute->called
constructor[ActionIMPL]
execute->exist

例外メッセージなどは出力されません。Java 8 1.8.25 64 ビットを使用しています。

アップデート

私のように勉強している読者にとって、これは正しい実行コードです。

呼び出し元のクラスを作成しました。

クラスコンストラクターにパラメーターとして渡す必要がある「アクション機能インターフェイスから実行する」空のメソッドを実装する必要があるため、MethodReference「空のコンストラクターである MethodReferenceCall のコンストラクター」を参照し、それを使用できます。

public class MethodReferenceCall {
    public MethodReferenceCall() {
        System.out.println("MethodReferenceCall class constructor called");
    }

    public static void main(String[] args) {
        MethodReferenceCall clazz = new MethodReferenceCall();
        MethodReferences constructorCaller = new MethodReferences(MethodReferenceCall::new);
        constructorCaller.execute();
    }
}
4

1 に答える 1

12

これ

MethodReferences clazz = new MethodReferences(() -> new ActionImpl());

メソッド参照を使用せず、ラムダ式を使用します。Action機能インターフェースは

public void perform();

そう

() -> new ActionImpl()

に似たものに翻訳されます

new Action() {
    public void perform() {
        new ActionImpl();
    }
}

同様に、

MethodReferences clazz = new MethodReferences(ActionImpl::new);

コンストラクタ参照を使用するはActionImpl::new、次のようなものに変換されます

new Action() {
    public void perform() {
        new ActionImpl();
    }
}

これActionImpl::newは を呼び出しませんnew ActionImpl()。期待される型のインスタンスに解決され、そのコンストラクターを呼び出す機能インターフェイス メソッドが実装されます。

于 2014-10-21T23:19:46.107 に答える