一、Java有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。(度娘文库是这么说的)
二、这篇文章主要介绍一下通过反射机制去实例化一个类的对象,然后调用其方法。本文主要介绍两种方式,第一种就是通过构造函数来实例化,第二种就是通过Class类的newnstance()方法进行实例化,下面我就通过代码来展示:
1、首先我建了一个Person类作为测试用的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
package
com.reflect.test;
/**
* @author 林楷鹏
* @description 测试用的
* @create 2014-11-27下午9:34:00
*
*/
public
class
Person {
private
int
age;
private
String name;
public
Person() {
}
public
Person(String name) {
this
.name = name;
}
public
Person(
int
age, String name) {
this
.age = age;
this
.name = name;
}
public
void
setAge(
int
age) {
this
.age = age;
}
public
void
setName(String name) {
this
.name = name;
}
public
int
getAge() {
return
age;
}
public
String getName() {
return
name;
}
}
|
2、通过构造函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
package
com.reflect.test;
import
java.lang.reflect.Constructor;
import
java.lang.reflect.InvocationTargetException;
import
java.lang.reflect.Method;
/**
* @author 林楷鹏
* @description 反射机制,通过构造函数实例化对象
* @create 2014-11-27下午9:32:05
*
*/
public
class
ReflectConstructor {
public
static
void
main(String[] args) {
Person person =
new
Person();
try
{
Class cls = Class.forName(person.getClass().getName());
//参数类型
Class[] params = {Integer.TYPE, String.
class
};
//参数值
Object[] values = {
15
,
"kroc"
};
//构造有两个参数的构造函数
Constructor constructor = cls.getDeclaredConstructor(params);
//根据构造函数,传入值生成实例
Object object = constructor.newInstance(values);
Method getAge = cls.getDeclaredMethod(
"getAge"
);
Method getName = cls.getDeclaredMethod(
"getName"
);
System.out.println(
"getAge = "
+ (Integer)getAge.invoke(object));
System.out.println(
"getName = "
+ (String)getName.invoke(object));
}
catch
(ClassNotFoundException e) {
e.printStackTrace();
System.out.println(
"ClassNotFoundException"
);
}
catch
(NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch
(SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch
(InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch
(IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch
(IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch
(InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
|
1
2
3
4
|
//构造有两个参数的构造函数
Constructor constructor = cls.getDeclaredConstructor(params);
//根据构造函数,传入值生成实例
Object object = constructor.newInstance(values);
|
运行结果如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
package
com.reflect.test;
import
java.lang.reflect.InvocationTargetException;
import
java.lang.reflect.Method;
/**
* @author 林楷鹏
* @description 反射机制,通过newInstance()实例化对象
* @create 2014-11-27下午9:41:01
*
*/
public
class
ReflectMethod {
public
static
void
main(String[] args) {
Person person =
new
Person();
try
{
Class cls = Class.forName(person.getClass().getName());
//生成实例,调用默认无参构造函数
Object object = cls.newInstance();
Method setName = cls.getDeclaredMethod(
"setName"
, String.
class
);
Method setAge = cls.getDeclaredMethod(
"setAge"
, Integer.TYPE);
setName.invoke(object,
"KrocLin"
);
setAge.invoke(object,
20
);
Method getAge = cls.getDeclaredMethod(
"getAge"
);
Method getName = cls.getDeclaredMethod(
"getName"
);
System.out.println(
"getAge = "
+ (Integer)getAge.invoke(object));
System.out.println(
"getName = "
+ (String)getName.invoke(object));
}
catch
(ClassNotFoundException e) {
e.printStackTrace();
System.out.println(
"ClassNotFoundException"
);
}
catch
(NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch
(SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch
(InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch
(IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch
(IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch
(InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
|
运行结果:
三、关于反射机制,可以做的事情还有很多,上面我为了简单展示就类似于getName这些方法名什么的都写死了,其实还可以通过反射去获取方法名,包括方法的返回类型啊、抛出异常等等都可以通过反射机制去得到。以后有时间就再写一些关于java反射机制的文章分享下,对于这个如果哪里写错了或者有什么更好的建议麻烦评论交流。