2016-07-01 4 views
1

私はInvoke dynamicの助けを借りてBeanを変換するJavaフレームワークを作成しています。 ASMで変換クラスを作成します。私はASMで、次のバイトコードを書くinvokedynamicを使用するときのジェネリック情報

target.setter(convert(source.getter())); 

mv.visitVarInsn(ALOAD, ARGUMENT_2); 
mv.visitVarInsn(ALOAD, ARGUMENT_1); 
mv.visitMethodInsn(INVOKEVIRTUAL, sourceClass, sourceGetter.getName(), Type.getMethodDescriptor(sourceGetter), false); 
mv.visitInvokeDynamicInsn("convert", Type.getMethodDescriptor(Type.getType(targetSetter.getParameterTypes()[0]), Type.getType(sourceGetter.getReturnType())), converterBootstrapMethod); 
mv.visitMethodInsn(INVOKEVIRTUAL, targetClass, targetSetter.getName(), Type.getMethodDescriptor(targetSetter), false); 

変換方法は、その後、特定の種類を扱うことができるコンバーターを検索するように見える変換を生成するために。これは次のようになります。

public static CallSite bootstrap(final MethodHandles.Lookup caller, final String name, final MethodType type) throws Exception { 
    final Class<?> sourceType = type.parameterType(0); 
    final Class<?> targetType = type.returnType(); 
    MethodHandle converter = findConverter(sourceType, targetType); 
    return new ConstantCallSite(converter.asType(type)); 
} 

これは、文字列から整数への変換では問題ありません。しかし、ジェネリック医薬品ではない。 ソースタイプはLjava/util/List;で、完全ではありませんLjava/util/List<Ljava/lang/String;>;

このブートストラップ方式でフルタイプを取得するにはどうすればよいですか?

+1

これは[タイプ消去](https://docs.oracle.com/javase/tutorial/java/generics/erasure.html)のためです。 –

+0

原因を知っています!しかし、今それを修正する方法! – SPee

答えて

0

呼び出し元の動的呼び出しサイトを管理している場合、追加の引数を渡すことができます。これらの引数の中で、実際のフィールド/ゲッタ名とその宣言クラスをcallsiteに渡す必要があります。

ブートストラップ方式でこの情報を使用すると、実際のフィールド/ゲッターを見つけて、リフレクションAPIを介して汎用情報を抽出できるようになりました。

関連する問題