私は昨晩Java8 Lambdaで遊んでいましたが、実行時にラムダ式を取得できるかどうかは疑問でした。要するに、ラムダ式は実行時に(静的な)メソッドに変換され、InvokeDynamicsを使って呼び出されます。 filter
がパラメータとしてPredicate<T>
を取ってカスタムメソッドになり実行時にラムダ式を取得することは可能ですか?
people.filter(person -> person.getAge() >= minAge);
:
はのは、このように例を見てみましょう。 このfilter
メソッドの中で、この場合、ラムダ式(person -> person.getAge() >= minAge
)と同様の(または同一の)形式で引数を取得するにはどうすればよいですか?
引数のクラスの生成されたバイトコードをASM5_BETAを使用して読み取ろうとしましたが、ClassVisitorとMethodVisitorを使用してラムダ式に関連付けられたメソッドに到達する以上に進めませんでした。
public <T> List<T> filter(Filter<T> expression) {
try {
Class<? extends Filter> expressionClass = expression.getClass();
byte[] content = getClassContent(expressionClass);
ClassReader classReader = new ClassReader(content);
classReader.accept(new PredicateClassVisitor(), 0);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
private byte[] getClassContent(Class<? extends Filter> expressionClazz) throws
IOException {
InputStream stream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(getClassName(expressionClazz.getName()));
return IOUtils.toByteArray(stream);
}
private String getClassName(String expressionClazz) {
return expressionClazz.substring(0, expressionClazz.indexOf('$'))
.replace('.', '/') + ".class";
}
static class PredicateClassVisitor extends ClassVisitor {
public PredicateClassVisitor() {
super(Opcodes.ASM4);
}
@Override
public MethodVisitor visitMethod(int i, String s, String s2, String s3,
String[] strings) {
return new PredicateMethodVisitor();
}
}
static class PredicateMethodVisitor extends MethodVisitor {
public PredicateMethodVisitor() {
super(Opcodes.ASM4);
}
@Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
Object... bsmArgs) {
for (Object object : bsmArgs) {
System.out.println(" " + object.toString());
}
}
}
私はこれが従うべき正しい道ではわからない、とそのような目的のためにASMまたはJDK8でより適切なツールがあった場合、私は思っていました。
何かアドバイスをありがとう;-) 敬具、 ザビエル
実際にここで何を達成しようとしていますか?あなたがこれを説明するまで、あなたに助言するのは難しいです。 –
「取得ラムダ式」とは、「生成する」という意味です。 BTWラムダ呼び出し自体はInvokeDynamicを超えていませんが、これはラムダ呼び出しオブジェクトを作成するプロセスでのみ使用されます。 –
私は、呼び出しコードで提供されたラムダ式をキャプチャしたいと思います。私はJVMの代わりにバイトコードを生成することについて話していません。上記の例から 'filter(Filter expression)'メソッドでは、与えられた 'expression'引数を' person-> person.getAge()> = minAge'ラムダに戻すことができます表現。これは実行可能ですか? –