繁体   English   中英

如何使用反射使用.class(非对象)参数调用Java中的方法

[英]How to invoke a method in java with .class (non-object) parameters using reflection

最近,我不得不使用反射来访问超类中的一些私有方法和字段。 这是我开始使用反射之前的样子:

            processSecondPassesOfType(PkDrivenByDefaultMapsIdSecondPass.class);
        processSecondPassesOfType(SetSimpleValueTypeSecondPass.class);
        processSecondPassesOfType(CopyIdentifierComponentSecondPass.class);
        processFkSecondPassInOrder();
        processSecondPassesOfType(CreateKeySecondPass.class);
        processSecondPassesOfType(SecondaryTableSecondPass.class);

现在,我必须调用通过反射获取的私有方法:

        Class<?> clazz = Class.forName("org.hibernate.cfg.Configuration");
        inSecondPass = true;
        Method m1 = clazz.getDeclaredMethod("processSecondPassesOfType", Class.class);
        m1.setAccessible(true);
        m1.invoke(PkDrivenByDefaultMapsIdSecondPass.class);

当我尝试运行此命令时,出现以下错误:

java.lang.IllegalArgumentException: object is not an instance of declaring class

那么,如何使用反射调用具有非对象参数的方法?

除非这是一个静态方法-你需要的实例来调用

在普通代码中,您可以执行以下操作:

foo.bar(x, y, z); 

foo上调用bar()

使用反射,逻辑会在某种程度上被逆转:

handleToBar = ...
handleToBar.invoke(foo, x, y, ...

换句话说:您不能“凭空”调用非静态方法。 您必须提供一些对象来调用。

当然,通常的免责声明是:A)反射是“邪恶的” B)仅在绝对必要时使用它,然后C)知道自己在做什么,D)避免调用私有的东西-这些是实现细节和主题改变。 您只能在运行时找到它,因为A)反射是“邪恶的”。

m1.invoke(PkDrivenByDefaultMapsIdSecondPass.class);

当使用java.lang.reflect.Method.invoke() 调用方法时,第一个参数是要在其上调用此特定方法的对象实例。 (如果该方法是静态的,则第一个参数应为null。)后续参数是该方法的参数。

因此,如果被调用的方法是静态的,则调用将为;

m.invoke(null, methodArguments);

如果被调用的方法不是静态的,则调用将为;

m.invoke(objectOnWhichMethodCalled, methodArguments);

如果基础方法引发异常,则它将被java.lang.reflect.InvocationTargetException包装。 可以使用异常链接机制的InvocationTargetException.getCause()方法来检索该方法的原始异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM