2016-06-22 2 views
0

ラムダからメソッド参照へリファクタリングしようとしましたメソッドリファレンスが呼び出し元のローカル変数を取得しないという違いがあるようですレキシカルスコープ?)。インラインコードとしてラムダを使用する場合、まったく問題はありません。 Javaラムダとメソッドリファレンス - 1つは呼び出し元のローカル変数を受け取りません

public class MethodRef { 

    public static void main(String[] args) { 
    String appender = "I am appended"; 

    //possible 
    appender("Hello! ", former -> { 
     StringBuilder builder = new StringBuilder(former); 
     builder.append(appender); 
     System.out.println(builder.toString()); 
    }); 

    //not possible 
    appender("Hello! ", this::theRef); 
    } 

    //Delegater 
    public static void appender(String former, Consumer<String> consumer){ 
     consumer.accept(former); 
    } 

    //Method Ref 
    public void theRef(String former){ 
    StringBuilder builder = new StringBuilder(former); 
    builder.append(appender); 
    System.out.println(builder.toString()); 
    } 
} 

は、私は方法ののparamリストは、任意の「アペンダ」を得ていないが、私は、発信者/消費者の範囲の字句VARSにアクセスするために使用することができます「隠された」paramは存在しないという事実を理解できますか?

+0

静的コンテキストからメンバーメソッドにアクセスしようとしています。 'theRef'メソッドのシグネチャを' public static void theRef(String former) 'に変更し、' this :: theRef'の代わりに 'MethodRef :: theRef'を使用してみてください。 Oracleのマニュアルの[静的メソッドのリファレンス](https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html)を参照してください。 – Jezor

答えて

2

いいえ、これはできません。

レキシカルスコープは、コンパイル時に解決されます。このメソッドは一般的な方法で記述され、どこからでも技術的に呼び出すことができます。したがって、コンパイラはすべての潜在的な呼び出しのレキシカルスコープを推測することはできません。

個別のメソッドを維持したい場合は、ラムダをラップして呼び出しをラップし、パラメータとしてローカル変数を渡すだけです。しかし、私はこれが本来の目標ではないと考えています。

1

いいえ、メソッドの外部にあるローカル変数にアクセスできる通常のメソッドを作成することはできません。

定義されているスコープからローカル変数のコピーを保持するlambdasの名前は、クロージャです。

私がJavaでクロージャを使用することを知っている他の唯一の方法は、匿名の内部クラスです。

関連する問題