Java 8でラムダ関数を作成し、そのクラス名を取得してから、そのクラス名から関数を再度インスタンス化したいと考えています。名前でJavaラムダ関数をインスタンス化する
これは私がしようとするものである:
import java.util.function.Consumer;
public class SimpleLambda
{
public static void call(String aLambdaClassName, String aArg) throws Exception
{
Class<Consumer<String>> lClass = (Class<Consumer<String>>) Class.forName(aLambdaClassName);
Consumer<String> newlamba = lClass.newInstance();
newlamba.accept(aArg);
}
public static void main(String[] args) throws Exception
{
{
// Attempt with a static method as lambda
Consumer<String> lambda = Host::action;
String classname = lambda.getClass().getName();
call(classname, "Hello world");
}
{
// Attempt with a locally defined lambda
Consumer<String> lambda = (s) -> { System.out.println(s); };
String classname = lambda.getClass().getName();
call(classname, "Hello world");
}
}
}
class Host {
public static void action(String aMessage) {
System.out.println(aMessage);
}
}
しかし、(静的メソッド参照を使用して、両方のバリアントで、ローカルでラムダ宣言を使用して)このコードで、私は例外を取得:
Exception in thread "main" java.lang.ClassNotFoundException: mypackage.SimpleLambda$$Lambda$1/471910020
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at mypackage.SimpleLambda.main(SimpleLambda.java:12)
私は静的メソッド参照を少なくとも再インスタンス化することができると期待していたでしょう...いいえ、明らかにそうではありません。
Groovy Closuresで同様のアプローチを使用していて、うまく機能しています。だから私はちょうどJava 8のラムダに間違って何かをしていますか、または名前でラムダをインスタンス化することはできませんか?私はラムダが(デ)シリアライズできるネット上のいくつかのヒントを発見したので、名前でインスタンス化することもできるはずです。
あなたはそれらと何をしようとしていますか?ラムダはインスタンス化されておらず、ただ*です。 – 4castle
本質的には、ラムダを単一の関数で静的な内部クラスのように扱いたいと思います。文字列パラメータだけを受け入れるAPIを渡す必要があるので、クラス名ごとに渡したいと思います。だから私はAPIの中で名前を取得すると、私はそれを呼び出すことができるようにクラス名からラムダを再作成したい。奇妙に聞こえる?はい、それは...ですが、私が言ったように:それはGroovyで行い、うまく動作します。私はJavaで動作しないだろうという気持ちがありますが、誰かがそれをどうやって行うのか手がかりがあれば、本当にクールです。 – rec
私はこの例をもっと使いやすくするために更新しました。 – rec