2

Riddle me this,

In my code, I am using a map to store all the methods of an object which have my annotation. Because of the way I wanted to use the map, I'm storing the java.reflection.Method object as the value, and the key is an array list containing the method name as a String and the parameter types as a Class[]

to create the map my code does the following:

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

This successfully returns me a map containing something similar to this:

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

I can examine the key and print the classes and know that its made up of an ArrayList where the first element is a String and the second is a Class[] containing two Strings

Whilst testing this code, I built an Array list which is equivalent to a key i knoiw exists in the map:

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

And I know this is equivalent to a current key with an assert:

assert tstKey == curKey

Which passes fine... However when I try to access the element by tstKey it returns null. Yet accessing the element by curKey returns the element.

This has left me scratching my head a little. If they are equivalent arrays, why can't I return the element using the built tstKey?

SIDENOTE: I tried using getParamTypes() on the CachedMethod instead of getParameterTypes on the actual method, however it returned null despite getParamsCount returning 2, any ideas why that would be?

4

1 回答 1

4

核心原因是it.parameterTypes返回一个Java Object 数组。因此,首先您需要更改以下内容:

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

现在真正的问题是ArrayList从地图中获取值时使用了哈希码。ArrayList 哈希码基于其元素的哈希码,Java 数组就是其中之一。Java 数组哈希码基于 Object 中所做的对象引用,因此没有 2 个数组将具有相同的哈希码。
如果您要打印两个密钥的哈希码,您会发现它们并不相同。

于 2013-03-24T15:59:46.847 回答