当我知道这个类时如何正确调用方法?

时间:2013-12-17 15:51:43

标签: java reflection methods invoke

我正在实施一个IdChecker程序,它检查项目的类和方法的“id”的唯一性。 IdChecker只在编译我的项目时才运行......在我推出一个版本之前。

对于类,很容易获得id,因为我只需要映射我的所有类然后调用MyClass.getField(“CLASS_ID”)。getShort(MyClass.getField(“CLASS_ID”));然后我创建一个包含className和classIdentifier的ClassWrapper。

对于方法,它有点复杂,因为我不能使用反射来访问方法本地的变量......但是......在我的项目中,我使用debuglogger来记录每个“进入方法“和”离开方法“。要获取本地变量,我想调用一个方法,然后在我的logBu​​ffer中读取此日志条目中的最后一个条目(谁是“leave-the-method”日志条目),我得到METHOD_ID。

我的问题:

我无法在类上调用它生成IllegalArgumentException的方法... 我不需要将参数传递给方法,我只想调用它们,我可以生成一个日志条目。

private void getMethodsList() throws IllegalArgumentException,
    IllegalAccessException, NoSuchFieldException, SecurityException   {
    final short METHOD_ID = 0x03;
    /* Log-entering the method */
    mLogger.logDebug((byte) 1, METHOD_ID);

    /* Create the MethodWrapper list corresponding
       to each element of the ClassWrapper list */
    for(Class<?> clazz : mClasses)
    {
        /* Get the declared methods from each class */
        for(Method method : clazz.getDeclaredMethods())
        {
            /* Get the name of the method */
            String newName = method.getName();
            short newIdentifier = 0;
            try
            {
                method.invoke(clazz, new Object[]{null});
                /* Get the identifier of the class */
                newIdentifier = AbstractDebugLogger.mLastMethodID;
            }

        .
        .
        .

1 个答案:

答案 0 :(得分:1)

method.invoke(...)需要一个实际可用于调用该方法的参数数组。在这种情况下,您给它{null},它适用于任何接受单个Object但没有其他函数的函数。要调用任意函数,您需要将参数列表的长度与函数所需的参数数量相匹配:

method.invoke(..., new Object[method.getParameterTypes().length])

这仍有一些问题。首先,调用的第一个参数不是您输入的类,而是该类的对象的实例(对于静态方法,为null)。在调用该类的实例方法之前,您需要搜索类的构造函数并构造该类的实例。 第二个问题是,这不适用于需要原语的函数,这些函数不能为空。您可以检查参数的类,并根据需要将null替换为0或false。 第三个也是最重要的问题,就是你很难做到这一点的原因是你实际上并不想调用这个方法。你想要检索有关方法的信息,在这种情况恰好存储在方法中。正确的解决方案是使用注释来存储附加到方法的信息:

@Retention(RetentionPolicy.RUNTIME)
@interface ID {
    int value();
}
...
@ID(1337)
void exampleMethod() { ... }
...
newIdentifier = method.getAnnotation(ID.class).value(); //returns 1337 for exampleMethod