2016-07-01 4 views
1

Invoke dynamic을 사용하여 bean을 변환하는 자바 프레임 워크를 만들고 있습니다. 나는 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

호출 동적 호출 사이트를 제어하는 ​​경우 추가 인수를 전달할 수 있습니다. 이러한 인수 내에서 실제 필드/getter 이름과 선언 클래스를 callsite에 전달해야합니다.

부트 스트랩 방법에서이 정보를 사용하면 실제 필드/getter를 찾고 리플렉션 API를 통해 일반 정보를 추출 할 수 있습니다.