一、执行期根据方法的名称来执行方法
下面的示例演示了这一操作:
import
java.lang.reflect.
*
;
public
class
method2
{
public
int
add(
int
a,
int
b)
{
return
a
+
b;
}
public
static
void
main(String args[])
{
try
{
Class cls
=
Class.forName(
"
method2
"
);
Class partypes[]
=
new
Class[
2
];
partypes[
0
]
=
Integer.TYPE;
partypes[
1
]
=
Integer.TYPE;
Method meth
=
cls.getMethod(
"
add
"
, partypes);
method2 methobj
=
new
method2();
Object arglist[]
=
new
Object[
2
];
arglist[
0
]
=
new
Integer(
37
);
arglist[
1
]
=
new
Integer(
47
);
Object retobj
=
meth.invoke(methobj, arglist);
Integer retval
=
(Integer) retobj;
System.out.println(retval.intvalue());
}
catch
(Throwable e)
{
System.err.println(e);
}
}
}
java.lang.reflect.
*
;
public
class
method2
{
public
int
add(
int
a,
int
b)
{
return
a
+
b;
}
public
static
void
main(String args[])
{
try
{
Class cls
=
Class.forName(
"
method2
"
);
Class partypes[]
=
new
Class[
2
];
partypes[
0
]
=
Integer.TYPE;
partypes[
1
]
=
Integer.TYPE;
Method meth
=
cls.getMethod(
"
add
"
, partypes);
method2 methobj
=
new
method2();
Object arglist[]
=
new
Object[
2
];
arglist[
0
]
=
new
Integer(
37
);
arglist[
1
]
=
new
Integer(
47
);
Object retobj
=
meth.invoke(methobj, arglist);
Integer retval
=
(Integer) retobj;
System.out.println(retval.intvalue());
}
catch
(Throwable e)
{
System.err.println(e);
}
}
}
注:上面划线的粗体字最好用Object methobj =
cls.newInstance();来代替,原因很明显如果这个类及方法事先都是清楚的也不需要用reflection了
假如一个程序在执行的某处的时候才知道需要执行某个方法,这个方法的名称是在程序的运行过程中指定的 (例如,JavaBean
开发环境中就会做这样的事),那么上面的程序演示了如何做到。上例中,getMethod 用于查找一个具有两个整型参数且名为 add
的方法。找到该方法并创建了相应的
Method 对象之后,在正确的对象实例中执行它。执行该方法的时候,需要提供一个参数列表,这在上例中是分别包装了整数 37 和 47 的两个
Integer 对象。执行方法的返回的同样是一个 Integer 对象,它封装了返回值 84。
二、执行期创建新的
对象
对于构造器,则不能像执行方法那样进行,因为执行一个构造器就意味着创建了一个新的对象
(准确的说,创建一个对象的过程包括分配内存和构造对象)。所以,与上例最相似的例子如下:
import
java.lang.reflect.
*
;
public
class
constructor2
{
public
constructor2()
{
}
public
constructor2(
int
a,
int
b)
{
System.out.println(
"
a =
"
+
a
+
"
b =
"
+
b);
}
public
static
void
main(String args[])
{
try
{
Class cls
=
Class.forName(
"
constructor2
"
);
Class partypes[]
=
new
Class[
2
];
partypes[
0
]
=
Integer.TYPE;
partypes[
1
]
=
Integer.TYPE;
Constructor ct
=
cls.getConstructor(partypes);
Object arglist[]
=
new
Object[
2
];
arglist[
0
]
=
new
Integer(
37
);
arglist[
1
]
=
new
Integer(
47
);
Object retobj
=
ct.newInstance(arglist);
}
catch
(Throwable e)
{
System.err.println(e);
}
}
}
java.lang.reflect.
*
;
public
class
constructor2
{
public
constructor2()
{
}
public
constructor2(
int
a,
int
b)
{
System.out.println(
"
a =
"
+
a
+
"
b =
"
+
b);
}
public
static
void
main(String args[])
{
try
{
Class cls
=
Class.forName(
"
constructor2
"
);
Class partypes[]
=
new
Class[
2
];
partypes[
0
]
=
Integer.TYPE;
partypes[
1
]
=
Integer.TYPE;
Constructor ct
=
cls.getConstructor(partypes);
Object arglist[]
=
new
Object[
2
];
arglist[
0
]
=
new
Integer(
37
);
arglist[
1
]
=
new
Integer(
47
);
Object retobj
=
ct.newInstance(arglist);
}
catch
(Throwable e)
{
System.err.println(e);
}
}
}
三、改变字段(域)的值
reflection 的还有一个用处就是改变对象数据字段的值。reflection
可以从正在运行的程序中根据名称找到对象的字段并改变它,下面的例子可以说明这一点:
import
java.lang.reflect.
*
;
public
class
field2
{
public
double
d;
public
static
void
main(String args[])
{
try
{
Class cls
=
Class.forName(
"
field2
"
);
Field fld
=
cls.getField(
"
d
"
);
field2 f2obj
=
new
field2();
System.out.println(
"
d =
"
+
f2obj.d);
fld.setDouble(f2obj,
12.34
);
System.out.println(
"
d =
"
+
f2obj.d);
}
catch
(Throwable e)
{
System.err.println(e);
}
}
}
java.lang.reflect.
*
;
public
class
field2
{
public
double
d;
public
static
void
main(String args[])
{
try
{
Class cls
=
Class.forName(
"
field2
"
);
Field fld
=
cls.getField(
"
d
"
);
field2 f2obj
=
new
field2();
System.out.println(
"
d =
"
+
f2obj.d);
fld.setDouble(f2obj,
12.34
);
System.out.println(
"
d =
"
+
f2obj.d);
}
catch
(Throwable e)
{
System.err.println(e);
}
}
}
这个例子中,字段 d 的值被变为了 12.34。
实际开发时用
Common BeanUtils
http://www.blogjava.net/RongHao/archive/2006/01/17/28322.html