1

リフレクションプロキシを使用して、パブリックAPIで追加のチェックを実行しています。基本的に、呼び出し元が手に入れるオブジェクトが実際のオブジェクトのプロキシになるように、そこから戻ってくるすべてのオブジェクトをラップしたいと思います。

Javaにはまだ全体の消去の問題があるので、ラップされたオブジェクトのタイプをJavaと一緒に渡します。APIへのエントリは単一の非ジェネリックインターフェイスであるため、すべてがどのタイプであるかを知っておく必要があります。

public class ProxyInvocationHandler implements InvocationHandler {
    private final Object delegate;
    private final Type delegateType;

    public ProxyInvocationHandler(Object delegate, Type delegateType) {
        this.delegate = delegate;
        this.delegateType = delegateType;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
        // Omitted: additional checks performed here.

        Object result = method.invoke(delegate, args);

        Type returnType = method.getGenericReturnType();

        // e.g. if delegateType is List<Cat> and the method is the get method,
        // returnType would be E but resultType should be Cat.
        Type resultType = ???

        // Utility method I will omit, it just creates another proxy instance
        // using its own invocation handler.
        return ProxyUtils.wrap(result, resultType);
    }
}

Type / ParametrizedType APIを見回しましたが、これを計算するのに十分な情報であるはずなresultTypeのにdelegateType、取得する方法が見つからないようです。returnType

これを行うための「適切な」方法は何ですか?

4

2 に答える 2

1

その目的でJavaClassMateを使用できます。com.fasterxml.classmate.GenericTypeタイプトークンには次のものを使用する必要があります。

GenericType<?> delegateType = new GenericType<List<Cat>>() {};

「スーパータイプトークン」パターン{}と呼ばれる空に注意してください。

TypeResolver typeResolver = new TypeResolver();
MemberResolver memberResolver = new MemberResolver(

ResolvedType type = typeResolver.resolve(delegateType);
ResolvedTypeWithMembers members = memberResolver.resolve(type, null, null);
ResolvedMethod[] methods = members.getMemberMethods();

Map結果を:にキャッシュします。

Map<Method, ResolvedMethod> resolved = new HashMap<>();
for (ResolvedMethod method: methods) {
    resolved.put(method.getRawMember(), method);
}

これで、によって宣言されたメソッドがある場合delegateType、つまり、解決された戻り型Listを取得できます。

Method method = List.class.getMethod("get", int.class);
ResolvedType resultType = resolved.get(method).getReturnType();
System.out.println("resultType = " + resultType);              // prints resultType = Cat
于 2012-09-25T15:13:50.013 に答える
1

将来来る人々のためのグアバの方法は次のとおりです。

...
Type returnType = method.getGenericReturnType();
TypeToken<?> resultType = TypeToken.of(delegateType).resolveType(returnType);

TypeToken<?>少し簡単にするために、delegateTypeのタイプをに変更しました。LoadingCacheそしてもちろん、パフォーマンスを適切な速度まで下げるために、(を使用して)かなりのキャッシュを追加しました。彼らの解決コードは、同じことをした私の最初のハッキングされたコードよりも遅かった。違いは、正しく行われているという自信があることです。

于 2012-09-28T06:20:37.383 に答える