- 浏览: 4591 次
- 性别:
- 来自: 北京
文章分类
最新评论
了解下java反射机制之Method invoke执行调用方法例子
昨天在群里跟大家讨论了下java反射调用可变参数的问题,这个问题起因是我们需要反射调用另一个部门提供的方法,我同事说java不能反射调用可变参数的方法,于是我写了个demo证明了他这个观点的错误。但是测试过程中,有一点我不明白,就是反射调用可变参数的方法时,为什么一定要保证传入的参数数组长度为1,在群里跟大家讨论了很多,没有得到确切的答案,参照网上大牛写的东西和我自己跟源码的过程,记录如下:
1.两个类,一个父类,一个子类
[java] view plain copy print?
package com.reflect.test;
public class BaseObject {
public void getObjectName(){
System.out.println("BaseObject");
}
}
[java] view plain copy print?
package com.reflect.test;
public class SubObject extends BaseObject{
@Override
public void getObjectName() {
System.out.println("SubObject");
}
public void getParamsLength(String...params){
System.out.println("param's length is:"+params.length);
}
public void getParamsLength(String param1,String param2){
System.out.println(param1 + "-" + param2);
}
}
2.测试类,主要测试重载方法的调用、可变参数方法的调用、定参方法的调用
[java] view plain copy print?
package com.reflect.test;
import java.lang.reflect.Method;
public class ReflectTest {
private static final String BASE_OBJECT_PATH = "com.reflect.test.BaseObject";
private static final String SUB_OBJECT_PATH = "com.reflect.test.SubObject";
public static void main(String[] args) throws Exception{
Class bClazz = Class.forName(BASE_OBJECT_PATH);
Class sClazz = Class.forName(SUB_OBJECT_PATH);
Object bObj = bClazz.newInstance();//父类实例
Object sObj = sClazz.newInstance();//子类实例
//1.反射调用子类父类的重载方法
//多态+动态绑定
Method bMethod = bClazz.getDeclaredMethod("getObjectName");
bMethod.invoke(bObj);//父类的bMethod调用父类的getObjectName()
bMethod.invoke(sObj);//父类的bMethod调用子类的getObjectName();
Method sMethod = sClazz.getDeclaredMethod("getObjectName");
//不符合多态和动态绑定
//sMethod.invoke(bObj);//sMethod调用父类的getObjectName(),会报错:java.lang.IllegalArgumentException: object is not an instance of declaring class
sMethod.invoke(sObj);
//2.反射调用可变参数的方法
Method changeMethod = sClazz.getDeclaredMethod("getParamsLength", String[].class);
//可变参数必须这样封装,因为java反射内部实现做了参数个数为1的判断,如果参数长度不为1,则会抛出异常
String[] strParams = {"a","b","c"};
Object[] cParams = {strParams};
changeMethod.invoke(sObj, cParams);
//3.反射调用固定长度参数的方法
Method unChangeMethod1 = sClazz.getDeclaredMethod("getParamsLength", String.class,String.class);
unChangeMethod1.invoke(sObj, "Hello","Java");
//也可以写成这样
Class[] clazzs = {String.class,String.class};
Method unChangeMethod2 = sClazz.getDeclaredMethod("getParamsLength", clazzs);
unChangeMethod2.invoke(sObj, "Hello","Java");
//下面的这种调用形式也是可以的,不过会报警告
//String[] params1 = {"Hello","Java"};
//unChangeMethod1.invoke(sObj, params1);
}
}
下面是JDK里面Method 的invoke方法的源码
从代码中可以看出,先检查 AccessibleObject的override属性是否为true(override属性默认为false)。AccessibleObject是Method,Field,Constructor的父类,可调用setAccessible方法改变,如果设置为true,则表示可以忽略访问权限的限制,直接调用。
如果不是ture,则要进行访问权限检测。用Reflection的quickCheckMemberAccess方法先检查是不是public的,如果不是再用Reflection.getCallerClass()方法获得到调用这个方法的Class,然后做是否有权限访问的校验,校验之后缓存一次,以便下次如果还是这个类来调用就不用去做校验了,直接用上次的结果。
[java] view plain copy print?
@CallerSensitive
public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
// Until there is hotspot @CallerSensitive support
// can't call Reflection.getCallerClass() here
// Workaround for now: add a frame getCallerClass to
// make the caller at stack depth 2
Class caller = getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
MethodAccessor ma = methodAccessor; // read volatile
if (ma == null) {
ma = acquireMethodAccessor();
}
return ma.invoke(obj, args);
}
/验证的代码,securityCheckCache就是JDK做的缓存
volatile Object securityCheckCache;
void checkAccess(Class caller, Class clazz, Object obj, int modifiers)
throws IllegalAccessException
{
if (caller == clazz) { // quick check
return; // ACCESS IS OK
}
Object cache = securityCheckCache; // read volatile
Class targetClass = clazz;
if (obj != null
&& Modifier.isProtected(modifiers)
&& ((targetClass = obj.getClass()) != clazz)) {
// Must match a 2-list of { caller, targetClass }.
if (cache instanceof Class[]) {
Class[] cache2 = (Class[]) cache;
if (cache2[1] == targetClass &&
cache2[0] == caller) {
return; // ACCESS IS OK
}
// (Test cache[1] first since range check for [1]
// subsumes range check for [0].)
}
} else if (cache == caller) {
// Non-protected case (or obj.class == this.clazz).
return; // ACCESS IS OK
}
// If no return, fall through to the slow path.
slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass);
}
然后就是调用MethodAccessor的invoke方法了。
调用MethodAccessor的invoke方法。每个Method对象包含一个root对象,root对象里持有一个MethodAccessor对象。这个对象由ReflectionFactory方法生成,ReflectionFactory对象在Method类中是static final的由native方法实例化。代码片段如下;
[java] view plain copy print?
//Method类中的代码片段,生成MethodAccessor
private volatile MethodAccessor methodAccessor;
private Method root;
private MethodAccessor acquireMethodAccessor() {
// First check to see if one has been created yet, and take it
// if so
MethodAccessor tmp = null;
if (root != null) tmp = root.getMethodAccessor();
if (tmp != null) {
methodAccessor = tmp;
} else {
// Otherwise fabricate one and propagate it up to the root
tmp = reflectionFactory.newMethodAccessor(this);
setMethodAccessor(tmp);
}
return tmp;
}
// reflectionFactory在父类AccessibleObject中定义,代码片段如下:
static final ReflectionFactory reflectionFactory =
AccessController.doPrivileged(
new sun.reflect.ReflectionFactory.GetReflectionFactoryAction());
ReflectionFactory生成MethodAccessor:如果noInflation的属性为true则直接返回MethodAccessorGenerator创建的一个MethodAccessor,否则返回DelegatingMethodAccessorImpl,并将他与一个NativeMethodAccessorImpl互相引用。但DelegatingMethodAccessorImpl执行invoke方法的时候又委托给NativeMethodAccessorImpl了。代码片段如下:
[java] view plain copy print?
public MethodAccessor newMethodAccessor(Method paramMethod) {
checkInitted();
if (noInflation) {
return new MethodAccessorGenerator().generateMethod(paramMethod.getDeclaringClass(), paramMethod.getName(), paramMethod.getParameterTypes(), paramMethod.getReturnType(), paramMethod.getExceptionTypes(), paramMethod.getModifiers());
}
NativeMethodAccessorImpl localNativeMethodAccessorImpl = new NativeMethodAccessorImpl(paramMethod);
DelegatingMethodAccessorImpl localDelegatingMethodAccessorImpl = new DelegatingMethodAccessorImpl(localNativeMethodAccessorImpl);
localNativeMethodAccessorImpl.setParent(localDelegatingMethodAccessorImpl);
return localDelegatingMethodAccessorImpl;
}
MethodAccessor实现有两个版本,一个是Java实现的,另一个是native code实现的。Java实现的版本在初始化时需要较多时间,但长久来说性能较好;native版本正好相反,启动时相对较快,但运行时间长了之后速度就比不过Java版了。这是HotSpot的优化方式带来的性能特性,同时也是许多虚拟机的共同点:跨越native边界会对优化有阻碍作用,它就像个黑箱一样让虚拟机难以分析也将其内联,于是运行时间长了之后反而是托管版本的代码更快些。 为了权衡两个版本的性能,Sun的JDK使用了“inflation”的技巧:让Java方法在被反射调用时,开头若干次使用native版,等反射调用次数超过阈值时则生成一个专用的MethodAccessor实现类,生成其中的invoke()方法的字节码,以后对该Java方法的反射调用就会使用Java版。
看下NativeMethodAccessorImpl 中的invoke方法:
代码片段如下:
[java] view plain copy print?
package sun.reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
class NativeMethodAccessorImpl extends MethodAccessorImpl
{
private Method method;
private DelegatingMethodAccessorImpl parent;
private int numInvocations;
NativeMethodAccessorImpl(Method paramMethod)
{
this.method = paramMethod;
}
public Object invoke(Object paramObject, Object[] paramArrayOfObject)
throws IllegalArgumentException, InvocationTargetException
{
if (++this.numInvocations > ReflectionFactory.inflationThreshold()) {
MethodAccessorImpl localMethodAccessorImpl = (MethodAccessorImpl)new MethodAccessorGenerator().generateMethod(this.method.getDeclaringClass(), this.method.getName(), this.method.getParameterTypes(), this.method.getReturnType(), this.method.getExceptionTypes(), this.method.getModifiers());
this.parent.setDelegate(localMethodAccessorImpl);
}
return invoke0(this.method, paramObject, paramArrayOfObject);
}
void setParent(DelegatingMethodAccessorImpl paramDelegatingMethodAccessorImpl) {
this.parent = paramDelegatingMethodAccessorImpl;
}
private static native Object invoke0(Method paramMethod, Object paramObject, Object[] paramArrayOfObject);
}
调用natiave方法invoke0执行方法调用.
注意这里有一个计数器numInvocations,每调用一次方法+1,当比 ReflectionFactory.inflationThreshold(15)大的时候,用MethodAccessorGenerator创建一个MethodAccessor,并把之前的DelegatingMethodAccessorImpl引用替换为现在新创建的。下一次DelegatingMethodAccessorImpl就不会再交给NativeMethodAccessorImpl执行了,而是交给新生成的java字节码的MethodAccessor
每次NativeMethodAccessorImpl.invoke()方法被调用时,都会增加一个调用次数计数器,看超过阈值没有;一旦超过,则调用MethodAccessorGenerator.generateMethod()来生成Java版的MethodAccessor的实现类,并且改变DelegatingMethodAccessorImpl所引用的MethodAccessor为Java版。后续经由DelegatingMethodAccessorImpl.invoke()调用到的就是Java版的实现了。
注意到关键的invoke0()方法是个native方法。它在HotSpot VM里是由JVM_InvokeMethod()函数所支持的,是用C写的
为了验证这个结论,我故意写出一个非法参数,循环调用16次并catch下异常,结果如下:从结果中看出,前15次都是调用NativeMethodAccessorImpl,第16次开始就是调用DelegatingMethodAccessorImpl了。
[java] view plain copy print?
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.reflect.test.ReflectTest.main(ReflectTest.java:44)
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.reflect.test.ReflectTest.main(ReflectTest.java:44)
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.reflect.test.ReflectTest.main(ReflectTest.java:44)
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.reflect.test.ReflectTest.main(ReflectTest.java:44)
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.reflect.test.ReflectTest.main(ReflectTest.java:44)
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.reflect.test.ReflectTest.main(ReflectTest.java:44)
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.reflect.test.ReflectTest.main(ReflectTest.java:44)
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.reflect.test.ReflectTest.main(ReflectTest.java:44)
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.reflect.test.ReflectTest.main(ReflectTest.java:44)
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.reflect.test.ReflectTest.main(ReflectTest.java:44)
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.reflect.test.ReflectTest.main(ReflectTest.java:44)
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.reflect.test.ReflectTest.main(ReflectTest.java:44)
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.reflect.test.ReflectTest.main(ReflectTest.java:44)
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.reflect.test.ReflectTest.main(ReflectTest.java:44)
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.reflect.test.ReflectTest.main(ReflectTest.java:44)
java.lang.IllegalArgumentException
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.reflect.test.ReflectTest.main(ReflectTest.java:44)
下面看看java版的DelegatingMethodAccessorImpl的实现:
[java] view plain copy print?
package sun.reflect;
import java.lang.reflect.InvocationTargetException;
class DelegatingMethodAccessorImpl extends MethodAccessorImpl
{
private MethodAccessorImpl delegate;
DelegatingMethodAccessorImpl(MethodAccessorImpl paramMethodAccessorImpl)
{
setDelegate(paramMethodAccessorImpl);
}
public Object invoke(Object paramObject, Object[] paramArrayOfObject)
throws IllegalArgumentException, InvocationTargetException
{
return this.delegate.invoke(paramObject, paramArrayOfObject);
}
void setDelegate(MethodAccessorImpl paramMethodAccessorImpl) {
this.delegate = paramMethodAccessorImpl;
}
package sun.reflect;
public class GeneratedMethodAccessor1 extends MethodAccessorImpl {
public GeneratedMethodAccessor1() {
super();
}
public Object invoke(Object obj, Object[] args)
throws IllegalArgumentException, InvocationTargetException {
// prepare the target and parameters
if (obj == null) throw new NullPointerException();
try {
A target = (A) obj;
if (args.length != 1) throw new IllegalArgumentException();
String arg0 = (String) args[0];
} catch (ClassCastException e) {
throw new IllegalArgumentException(e.toString());
} catch (NullPointerException e) {
throw new IllegalArgumentException(e.toString());
}
// make the invocation
try {
target.foo(arg0);
} catch (Throwable t) {
throw new InvocationTargetException(t);
}
}
}
if (args.length != 1) throw new IllegalArgumentException();这一句就能解释我之前的疑问了,这块会判断参数数组的长度,如果长度不等于1,就会抛出非法参数的异常。
而且MethodAccessor会做强制类型转换再进行方法调用,但父类强制转化成子类的的时候就会报错类型不匹配错误了,所以如果变量的引用声明是父但实际指向的对象是子,那么这种调用也是可以的。
文章来源:http://www.meiyuanxing.com/
相关推荐
通过8个demo,你可以逐步深入理解Java反射机制,从简单的获取类信息,到创建对象,调用方法,访问字段,再到处理注解和泛型,全方位掌握这一强大的工具。每个demo都应该设计为解决一个特定的问题,例如如何动态调用...
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部结构。通过反射,开发者可以动态地获取类的信息并调用其方法,创建对象,访问私有成员,甚至改变类的行为。在深入...
Java反射为程序提供了一种强大的动态性,让我们可以在运行时了解和操作类的信息。然而,由于反射操作可能会破坏封装性,因此在实际开发中应谨慎使用,避免引入安全风险和性能问题。学习并理解反射机制,可以帮助我们...
下面我们将深入探讨这个小例子以及Java反射机制的相关知识点。 首先,`Class.forName()`方法在例子中被用来动态加载类。`Class.forName(String className)`接收一个类的全名(包括包名),然后返回对应的`Class`...
### Java反射机制详解 #### 一、反射机制是什么 反射机制是Java编程语言的一个核心特性,它允许程序在运行时动态地获取类的信息,并且能够动态地创建对象和调用对象的方法。简单来说,反射机制使得Java程序可以...
### Java反射机制应用详解 #### 一、Java反射机制简介 Java反射机制是Java语言提供的一种能在运行时分析类信息并动态操作对象的功能。通过反射,我们可以在程序运行期间获取类的信息(如类名、方法名等),创建...
在这个例子中,我们首先通过`Class.forName()`方法动态加载了`Example`类,然后获取了`printMessage`方法的`Method`对象,接着创建了`Example`类的实例,并通过`Method`对象的`invoke()`方法调用了`printMessage`...
反射机制使得我们能够在运行时动态地获取类的信息,并且能够创建对象、调用方法、访问字段,甚至改变类的行为。在Java中,`java.lang.reflect`包提供了对反射的支持。 在“反射,动态加载指定类调用类中的方法”这...
在给出的“JavaClass”示例中,可能包含了一个或多个展示如何使用Java反射的代码片段,可能涉及到创建`Class`对象、获取和调用方法、访问字段等内容。通过分析这些例子,你可以更深入地理解Java反射的使用方式及其在...
之后,可以调用`Method.invoke(obj, args)`来执行指定对象上的方法。 4. **访问字段(Field)**:使用`Class.getFields()`获取公共字段,`Class.getDeclaredFields()`获取所有字段。`Field.set(obj, value)`用来设置...
Java反射机制是Java语言提供的一种...通过上述步骤,我们可以看到Java反射机制如何实现动态调用类的简单方法。这种技术在需要动态执行代码或实现通用功能的场景下非常有用,但使用时应权衡其带来的安全性和性能影响。
Java反射是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Spring框架中,反射扮演着核心角色,...希望这个简单的反射例子能帮助你更好地理解和运用Java反射。
Java反射机制是Java语言中一个强大的特性,它允许在运行时检查类、接口、字段和方法的信息,并且能够动态地创建对象和调用方法。在Java编程中,反射机制为程序提供了灵活的控制,使开发者可以对代码进行更加深入的...
`Method`对象的`invoke()`方法用于在指定的对象上执行该方法。 在给定的例子中,`Reflect`类的`ReflectCar()`方法展示了如何使用反射来创建`Car`类的实例,设置其属性并调用方法。首先,它通过`Thread.current...
通过本文的学习,我们了解到Java反射机制中`Constructor`、`Method`、`Field`以及`Class`类的基本使用方法。这些工具不仅增强了程序的灵活性,还提供了强大的扩展能力。在实际开发中合理利用反射机制,可以有效提升...
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查并操作类、接口、字段和方法的信息。这种动态类型的能力使得Java代码能够处理未知或未提前定义的对象,增强了程序的灵活性和可扩展性。在"Java...
在这个例子中,`GetMethod`用于获取`TestClass`的`PrintMessage`方法,然后`Invoke`方法被用来在创建的实例上执行这个方法,传入参数"Hello, World!"。 反射和Invoke的应用场景广泛,包括但不限于: 1. **插件系统*...
反射还能用于实例化对象(`Class.newInstance()`),调用方法(`Method.invoke(Object obj, Object... args)`)以及访问和修改字段值。 在"ThreadMain"这个文件中,可能包含了一个演示如何使用线程池和反射机制的...