2

これをなぞなぞ、

私のコードでは、マップを使用して、アノテーションを持つオブジェクトのすべてのメソッドを格納しています。マップの使用方法のため、java.reflection.Methodオブジェクトを値として格納しています。キーは、メソッド名を文字列として、パラメータータイプをClass[]として含む配列リストです。

マップを作成するために、私のコードは次のことを行います。

def map = [:]
Foo.metaClass.methods*.cachedMethod.each { 
    if(it.isAnnotationPresent(Test.class)) { 
        map << [([it.name, it.parameterTypes]):it] 
    } 
}

これにより、次のようなものを含むマップが正常に返されます。

[[exampleMethod, [class java.lang.String, class java.lang.String]]:public java.util.List Foo.exampleMethod(java.lang.String,java.lang.String)]

ArrayListキーを調べてクラスを印刷すると、最初の要素がaStringで、2番目の要素がClass[]2つStringの要素を含むで構成されていることがわかります。

このコードをテストしている間、私はマップに存在するキーと同等の配列リストを作成しました。

def tstKey = ["exampleMethod" as String, [String.class, String.class]]

そして、これはアサートのある現在のキーと同等であることを私は知っています:

assert tstKey == curKey

これは問題なく通過します...しかし、tstKeyそれによって要素にアクセスしようとすると、nullが返されます。ただし、によって要素にアクセスすると、要素がcurKey返されます。

これで少し頭をかいてしまいました。それらが同等の配列である場合、ビルドを使用して要素を返すことができないのはなぜtstKeyですか?

サイドノート:実際のメソッドではgetParamTypes()なくCachedMethodで使用しようとしましたが、返されたにもかかわらずnullが返されました。なぜそうなるのでしょうか?getParameterTypesgetParamsCount2

4

1 に答える 1

4

主な理由はit.parameterTypes、Javaオブジェクト配列を返すことです。したがって、まず最初に、以下を変更する必要があります。

def tstKey = ["exampleMethod" as String, [String.class, String.class] as Class<?>[]]

ここでの本当の問題はArrayList、マップから値を取得するときにハッシュコードが使用されることです。ArrayListハッシュコードはその要素のハッシュコードに基づいており、そのうちの1つはJava配列です。Java配列ハッシュコードは、Objectで行われるようにオブジェクト参照に基づいているため、2つの配列が同じハッシュコードを持つことはありません。
2つのキーのハッシュコードを印刷すると、それらが同じではないことがわかります。

于 2013-03-24T15:59:46.847 に答える