2016-03-10 7 views
5

私のコードでJava 8メソッド参照を使用しようとしています。使用可能なメソッド参照には4つのタイプがあります。Java 8:メソッド参照バインドレシーバとアンバインドレシーバの違い

  1. スタティックメソッドリファレンス。
  2. インスタンスメソッド(バウンドレシーバ)。
  3. インスタンスメソッド(UnBoundレシーバ)。
  4. コンストラクタ参照。 Static method referenceConstructor reference

私は何の問題もないが、Instance Method (Bound receiver)Instance Method (UnBound receiver)は本当に私を混乱。

objectRef::Instance Method 

受信機UnBoundでは、我々のようなメソッド呼び出しのためのクラス名を使用している:Bound受信機では、我々のようなメソッド呼び出しのためのオブジェクト参照変数を使用している

ClassName::Instance Method. 

をI、次の質問を持っています:

  1. インスタンスメソッドのさまざまなタイプのメソッド参照の必要性はありますか?
  2. BoundUnboundレシーバメソッドリファレンスの違いは何ですか?
  3. ここではBoundの受信機を使用する必要があります。また、受信機はどこでUnboundを使用しますか?

私もJava 8 language features booksからBoundUnbound受信機の説明を見つけましたが、それでも実際の概念に混乱していました。

答えて

7

String::lengthなどの結合していない受信機のアイデアは、あなたがはラムダのパラメータの1つとして供給されることをオブジェクトに 方法を参考にしていることです。たとえば、 ラムダ式(String s) -> s.toUpperCase()は、String::toUpperCaseと書き直すことができます。

しかし、あなたはすでにを存在外部のオブジェクトへ ラムダでメソッドを呼び出しているとき有界は状況を指します。例えば、ラムダ式() -> expensiveTransaction.getValue()は、expensiveTransaction::getValueと書き直すことができます。 ClassName::staticMethod

(arg0, rest) -> arg0.instanceMethod(rest)ClassName::instanceMethodarg0タイプClassNameである)

(args) -> expr.instanceMethod(args) ことができる方法を参照の3つの異なる方法

(args) -> ClassName.staticMethod(args) ため

状況であってもよいexpr::instanceMethod

することができます

回答済みJava 8のアクションブック

6

基本的に、バインドされていない受信者は、インスタンスメソッドを、宣言型の最初のパラメータを持つ静的メソッドであるかのように使用できるため、必要なインスタンスを渡すことで関数として使用できます。バインドされた受信側では、「ターゲット」インスタンスは事実上関数の一部です。

の例では、これが明確になるかもしれない:

import java.util.function.*; 

public class Test { 

    private final String name; 

    public Test(String name) { 
     this.name = name; 
    } 

    public static void main(String[] args) { 
     Test t1 = new Test("t1"); 
     Test t2 = new Test("t2"); 

     Supplier<String> supplier = t2::method; 
     Function<Test, String> function = Test::method; 

     // No need to say which instance to call it on - 
     // the supplier is bound to t2    
     System.out.println(supplier.get()); 

     // The function is unbound, so you need to specify 
     // which instance to call it on 
     System.out.println(function.apply(t1)); 
     System.out.println(function.apply(t2)); 
    } 

    public String method() { 
     return name; 
    } 
} 
+0

小さなクエリあなたは書いています:サプライヤサプライヤ= t2 ::メソッド;コメントは://サプライヤはt1にバインドされています。それはタイプミスですか、それとも正しく理解していませんか? –

+1

@Ravindrababu:ちょうどタイプミス。今修正して... –

2

あなたは方法は、いくつかのクラスの特定のインスタンスに対して実行させたい場合は、あなたがバインドされた受信機を使用しています。例えば

Stream.of("x","y").forEach(System.out::println); 

PrintStreamのsepcificインスタンスにprintlnを実行する - System.outインスタンス。したがって、そのメソッド参照をforEachに渡した結果、System.out.println("x")System.out.println("y")が実行されます。

一方、クラスの不特定のインスタンスに対してメソッドを実行する場合は、バインドされていない受信側を使用できます。例えば

Stream.of("x","y","").filter(String::isEmpty); 

ストリームのStringインスタンスのそれぞれにisEmpty()を実行する - すなわち"x".isEmpty()"y".isEmpty()"".isEmpty()

関連する問題