2016-02-25 9 views
9

ラムダ式を使用すると、Javaは実際には匿名(非静的)クラスを作成します。非静的な内部クラスは、常にそれらの囲むオブジェクトへの参照を含みます。Javaラムダ式が囲むオブジェクトへの参照を持たない方法はありますか?

このラムダ式は、別のプロセスでラムダを呼び出す可能性のある別のライブラリから呼び出されたときに、呼び出されたオブジェクトが別のプロセスでクラスを見つけることができないため、クラスが見つかりません。

この例を考えてみます。

public class MyClass { 
    public void doSomething() { 
     remoteLambdaExecutor.executeLambda(value -> value.equals("test")); 
    } 
} 

ジャワ)は、特定の機能インタフェースを実装する匿名の内部クラスを作成し、executeLambda(にパラメータとして渡します。それから、remoteLambdaExecutorは、プロセスを横断してその匿名クラスを取得し、リモートで実行します。 リモートプロセスは、MyClassのについて何も知らないし、それが囲んでいるオブジェクト参照のためのMyClassを必要とするため

java.lang.ClassNotFoundException: MyClass 

がスローされます。

私はいつもAPIが期待する機能的なインターフェイスの静的な実装を使うことができますが、それは目的を破りラムダ機能を利用しません。

ラムダ式を使って解決する方法はありますか?

更新:何らかの形で別のプロセスにエクスポートされない限り、静的なクラスを使用することはできません。

+0

'異なるプロセスでラムダを呼び出す可能性があります.':交差点のように聞こえます – wero

+0

多分Javaはこれに対して間違った言語です。スクリプト言語が必要なのかもしれません。 –

答えて

6

あなたの最初の前提が間違っています。 JREはではなく、では匿名の内部クラスを生成します。クラスを生成する可能性がありますが、ラムダ式がクラスのメンバーthisまたはstaticにアクセスしていない場合はではなく、thisインスタンスへの参照を保持します。

ただし、これはクラス自体が不要であることを意味するものではありません。クラスはラムダ式のコードをホストしているので、常に必要になります。この点に関して、ネストされたクラスstaticを使用するあなたのソリューションは、コードの実行に必要なネストされたクラスstaticです。

クラスを実行するコードを含むクラスを転送せずにリモート実行施設にオブジェクトを転送する方法はありません(クラスがリモートサイトに既に存在している場合を除く)。

+1

つまり、Javaラムダは、LispラムダよりもC++関数ポインタに似ています。 Javaラムダは実行するコードを示しますが、実際にはそのコードは含まれていません。私はこれを認識していなかった。 –

+0

それ以外の場合は、周囲のスコープの変数へのアクセスもできません。https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#accessing-local-variables –

+0

Holger、正しい。私の前提は間違っていた。質問はまだ立っています。それを行う方法はありますか?多分そこはありますか? – ATrubka

関連する問題