本文实例讲述了Java反射机制概念、原理与用法。分享给大家供大家参考,具体如下:
反射机制是什么
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射机制能做什么
反射机制主要提供了以下功能:
① 在运行时判断任意一个对象所属的类;
② 在运行时构造任意一个类的对象;
③ 在运行时判断任意一个类所具有的成员变量和方法;
④ 在运行时调用任意一个对象的方法;
⑤ 生成动态代理。
反射机制的相关API
InterFace 接口
1
2
3
4
|
package com.app; public interface InterFace { void read() ; } |
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
39
40
41
42
43
44
|
package com.app; public class Person implements InterFace { private String id ; private String name ; public String age ; //构造函数1 public Person( ){ } //构造函数2 public Person( String id ){ this .id = id ; } //构造函数3 public Person( String id , String name ){ this .id = id ; this .name = name ; } public String getId() { return id; } public void setId(String id) { this .id = id; } public String getName() { return name; } public void setName(String name) { this .name = name; } public String getAge() { return age; } public void setAge(String age) { this .age = age; } /** * 静态方法 */ public static void update(){ } @Override public void read() { } } |
获取类:3种方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package com.app; public class T1 { public static void main(String[] args) { //第一种方法:forName try { Class<?> class1 = Class.forName( "com.app.Person" ); System.out.println( class1 ); } catch (ClassNotFoundException e) { e.printStackTrace(); } //第二张方法:class Class<?> class2 = Person. class ; //第三种方法:getClass Person person = new Person(); Class<?> class3 = person.getClass(); System.out.println( class2 ); System.out.println( class3 ); } } |
运行结果:
1
2
3
|
class com.app.Person class com.app.Person class com.app.Person |
获取所有的方法:getMethods( )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
package com.app; import java.lang.reflect.Method; public class T1 { public static void main(String[] args) { try { //创建类 Class<?> class1 = Class.forName( "com.app.Person" ); //获取所有的公共的方法 Method[] methods = class1.getMethods() ; for (Method method : methods) { System.out.println( method ); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } |
运行结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//自定义方法 public static void com.app.Person.update() public java.lang.String com.app.Person.getName() public void com.app.Person.read() public java.lang.String com.app.Person.getId() public void com.app.Person.setName(java.lang.String) public void com.app.Person.setId(java.lang.String) //父类Object类方法 public final void java.lang.Object.wait() throws java.lang.InterruptedException public final void java.lang.Object.wait( long , int ) throws java.lang.InterruptedException public final native void java.lang.Object.wait( long ) throws java.lang.InterruptedException public boolean java.lang.Object.equals(java.lang.Object) public java.lang.String java.lang.Object.toString() public native int java.lang.Object.hashCode() public final native java.lang.Class java.lang.Object.getClass() public final native void java.lang.Object.notify() public final native void java.lang.Object.notifyAll() |
获取所有实现的接口:getInterfaces()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package com.app; public class T1 { public static void main(String[] args) { try { //创建类 Class<?> class1 = Class.forName( "com.app.Person" ); //获取所有的接口 Class<?>[] interS = class1.getInterfaces() ; for (Class<?> class2 : interS ) { System.out.println( class2 ); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } |
运行结果:
1
|
interface com.app.InterFace |
获取父类:getSuperclass()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
package com.app; public class T1 { public static void main(String[] args) { try { //创建类 Class<?> class1 = Class.forName( "com.app.Person" ); //获取父类 Class<?> superclass = class1.getSuperclass() ; System.out.println( superclass ); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } |
运行结果:
1
2
|
//父类是Object类 class java.lang.Object |
获取所有的构造函数:getConstructors()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
package com.app; import java.lang.reflect.Constructor; public class T1 { public static void main(String[] args) { try { //创建类 Class<?> class1 = Class.forName( "com.app.Person" ); //获取所有的构造函数 Constructor<?>[] constructors = class1.getConstructors() ; for (Constructor<?> constructor : constructors) { System.out.println( constructor ); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } |
运行结果:
1
2
3
|
public com.app.Person(java.lang.String,java.lang.String) public com.app.Person(java.lang.String) public com.app.Person() |
获取所有的属性:getDeclaredFields();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
package com.app; import java.lang.reflect.Constructor; import java.lang.reflect.Field; public class T1 { public static void main(String[] args) { try { //创建类 Class<?> class1 = Class.forName( "com.app.Person" ); //取得本类的全部属性 Field[] field = class1.getDeclaredFields(); for (Field field2 : field) { System.out.println( field2 ); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } |
运行结果:
1
2
|
private java.lang.String com.app.Person.id private java.lang.String com.app.Person.name |
可以看出属性的修饰符是: private , 数据类型:String ,名字:id/name
创建实例:newInstance()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package com.app; public class T1 { public static void main(String[] args) { try { //创建类 Class<?> class1 = Class.forName( "com.app.Person" );; //创建实例化:相当于 new 了一个对象 Object object = class1.newInstance() ; //向下转型 Person person = (Person) object ; } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } |
getDeclaredFields 和 getFields 的区别
getDeclaredFields()获得某个类的所有申明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
getFields()获得某个类的所有的公共(public)的字段,包括父类。
小例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
package com.app; import java.lang.reflect.Field; public class T1 { public static void main(String[] args) { try { //创建类 Class<?> class1 = Class.forName( "com.app.Person" );; //获得所有的字段属性:包括 Field[] declaredFields = class1.getDeclaredFields() ; Field[] fields = class1.getFields() ; for ( Field field : declaredFields ){ System.out.println( "de-- " + field ); } for ( Field field : fields ){ System.out.println( "fields-- " + field ); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } |
运行结果:
1
2
3
4
|
de-- private java.lang.String com.app.Person.id de-- private java.lang.String com.app.Person.name de-- public java.lang.String com.app.Person.age fields-- public java.lang.String com.app.Person.age |
实战1:通过反射,获取对象实例,并且操作对象的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
package com.app; public class T1 { public static void main(String[] args) { try { //创建类 Class<?> class1 = Class.forName( "com.app.Person" );; //创建实例化:相当于 new 了一个对象 Object object = class1.newInstance() ; //向下转型 Person person = (Person) object ; person.setId( "100" ); person.setName( "jack" ) ; System.out.println( "id: " + person.getId() + " name: " + person.getName() ); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } |
运行结果:
1
|
id: 100 name: jack |
实战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
|
package com.app; import java.lang.reflect.Field; public class T1 { public static void main(String[] args) { try { //创建类 Class<?> class1 = Class.forName( "com.app.Person" ); //创建实例 Object person = class1.newInstance(); //获得id 属性 Field idField = class1.getDeclaredField( "id" ) ; //给id 属性赋值 idField.set( person , "100" ) ; //打印 person 的属性值 System.out.println( idField.get( person )); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace() ; } catch (ClassNotFoundException e) { e.printStackTrace(); } } } |
运行结果:
1
2
3
4
5
6
|
java.lang.IllegalAccessException: Class com.app.T1 can not access a member of class com.app.Person with modifiers "private" at sun.reflect.Reflection.ensureMemberAccess(Unknown Source) at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(Unknown Source) at java.lang.reflect.AccessibleObject.checkAccess(Unknown Source) at java.lang.reflect.Field.set(Unknown Source) at com.app.T1.main(T1.java: 20 ) |
程序崩溃,原因是:id 这个属性的是 private 私有的,不能修改它的值。
改进:
添加 idField.setAccessible( true );
完整的代码为:
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
|
package com.app; import java.lang.reflect.Field; public class T1 { public static void main(String[] args) { try { //创建类 Class<?> class1 = Class.forName( "com.app.Person" ); //创建实例 Object person = class1.newInstance(); //获得id 属性 Field idField = class1.getDeclaredField( "id" ) ; //打破封装 实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问 //由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的 idField.setAccessible( true ); //给id 属性赋值 idField.set( person , "100" ) ; //打印 person 的属性值 System.out.println( idField.get( person )); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace() ; } catch (ClassNotFoundException e) { e.printStackTrace(); } } } |
运行结果:
1
|
100 |
实战3:综合训练,反射操作属性和方法
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
57
58
59
60
|
package com.app; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class T1 { public static void main(String[] args) { try { //创建类 Class<?> class1 = Class.forName( "com.app.Person" ); //创建实例 Object person = class1.newInstance(); //获得id 属性 Field idField = class1.getDeclaredField( "id" ) ; //打破封装 实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问 //由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的 idField.setAccessible( true ); //给id 属性赋值 idField.set( person , "100" ) ; //获取 setName() 方法 Method setName = class1.getDeclaredMethod( "setName" , String. class ) ; //打破封装 setName.setAccessible( true ); //调用setName 方法。 setName.invoke( person , "jack" ) ; //获取name 字段 Field nameField = class1.getDeclaredField( "name" ) ; //打破封装 nameField.setAccessible( true ); //打印 person 的 id 属性值 String id_ = (String) idField.get( person ) ; System.out.println( "id: " + id_ ); //打印 person 的 name 属性值 String name_ = ( String)nameField.get( person ) ; System.out.println( "name: " + name_ ); //获取 getName 方法 Method getName = class1.getDeclaredMethod( "getName" ) ; //打破封装 getName.setAccessible( true ); //执行getName方法,并且接收返回值 String name_2 = (String) getName.invoke( person ) ; System.out.println( "name2: " + name_2 ); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace() ; } catch (ClassNotFoundException e) { e.printStackTrace(); } } } |
运行结果:
1
2
3
|
id: 100 name: jack name2: jack |
实战4:静态属性、静态方法调用
定义 Util 类
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
|
package com.app; public class Util { public static String name = "json" ; /** * 没有返回值,没有参数 */ public static void getTips(){ System.out.println( "执行了---------1111" ); } /** * 有返回值,没有参数 */ public static String getTip(){ System.out.println( "执行了---------2222" ); return "tip2" ; } /** * 没有返回值,有参数 * @param name */ public static void getTip( String name ){ System.out.println( "执行了---------3333 参数: " + name ); } /** * 有返回值,有参数 * @param id * @return */ public static String getTip( int id ){ System.out.println( "执行了---------4444 参数: " + id ); if ( id == 0 ){ return "tip1 444 --1 " ; } else { return "tip1 444 --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
|
package com.app; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class T1 { public static void main(String[] args) { try { //创建类 Class<?> class1 = Class.forName( "com.app.Util" ); //获取 nameField 属性 Field nameField = class1.getDeclaredField( "name" ) ; //获取 nameField 的值 String name_ = (String) nameField.get( nameField ) ; //输出值 System.out.println( name_ ); //没有返回值,没有参数 Method getTipMethod1 = class1.getDeclaredMethod( "getTips" ) ; getTipMethod1.invoke( null ) ; //有返回值,没有参数 Method getTipMethod2 = class1.getDeclaredMethod( "getTip" ) ; String result_2 = (String) getTipMethod2.invoke( null ) ; System.out.println( "返回值: " + result_2 ); //没有返回值,有参数 Method getTipMethod3 = class1.getDeclaredMethod( "getTip" , String. class ) ; String result_3 = (String) getTipMethod3.invoke( null , "第三个方法" ) ; System.out.println( "返回值: " + result_3 ); //有返回值,有参数 Method getTipMethod4 = class1.getDeclaredMethod( "getTip" , int . class ) ; String result_4 = (String) getTipMethod4.invoke( null , 1 ) ; System.out.println( "返回值: " + result_4 ); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace() ; } catch (ClassNotFoundException e) { e.printStackTrace(); } } } |
运行结果:
1
2
3
4
5
6
7
8
|
json 执行了--------- 1111 执行了--------- 2222 返回值: tip2 执行了--------- 3333 参数: 第三个方法 返回值: null 执行了--------- 4444 参数: 1 返回值: tip1 444 -- 2 |
当参数是 int 类型 和 Integer 类型,反射获取方法不一样
① 当参数是 int 类型时
1
2
3
4
5
6
|
/** * 没有返回值,有参数 * @param id */ public static void getTip( int id ){ } |
获取方法的时候需要用:int.class
。不能使用 Integer.class
. 会报错。
1
2
3
|
Method getTipMethod4 = class .getDeclaredMethod( "getTip" , int . class ) ; String result_4 = (String) getTipMethod4.invoke( null , 1 ) ; System.out.println( "返回值: " + result_4 ); |
② 当参数是 Integer类型时
1
2
3
4
5
6
|
/** * 没有返回值,有参数 * @param id */ public static void getTip( Integer id ){ } |
获取方法的时候需要用:Integer .class
。不能使用 int.class
. 会报错。
1
2
3
|
Method getTipMethod4 = class .getDeclaredMethod( "getTip" , Integer . class ) ; String result_4 = (String) getTipMethod4.invoke( null , 1 ) ; System.out.println( "返回值: " + result_4 ); |
创建对象实例
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
|
package com.app; public class Person{ private String id ; private String name ; //构造函数1 public Person( ){ System.out.println( "构造函数 无参" ); } //构造函数2 public Person( String id ){ this .id = id ; System.out.println( "构造函数 id : " + id ); } //构造函数3 public Person( String id , String name ){ this .id = id ; this .name = name ; System.out.println( "构造函数 id : " + id + " name: " + name ); } public String getId() { return id; } public void setId(String id) { this .id = id; } public String getName() { return name; } public void setName(String name) { this .name = name; } } |
创建实例实战
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
|
package com.app; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class T1 { public static void main(String[] args) { try { //创建类 Class<?> class1 = Class.forName( "com.app.Person" ); //无参构造函数 Object object = class1.newInstance() ; //有参构造函数:一个参数 Constructor<?> constructor = class1.getDeclaredConstructor( String. class ) ; constructor.newInstance( "1000" ) ; //有参构造函数:二个参数 Constructor<?> constructor2 = class1.getDeclaredConstructor( String. class , String. class ) ; constructor2.newInstance( "1001" , "jack" ) ; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace() ; } catch (ClassNotFoundException e) { e.printStackTrace(); } } } |
运行结果
1
2
3
|
构造函数 无参 构造函数 id : 1000 构造函数 id : 1001 name: jack |
总结
Class类提供了四个public方法,用于获取某个类的构造方法。
Constructor getConstructor(Class[] params) 根据构造函数的参数,返回一个具体的具有public属性的构造函数
Constructor getConstructors() 返回所有具有public属性的构造函数数组
Constructor getDeclaredConstructor(Class[] params) 根据构造函数的参数,返回一个具体的构造函数(不分public和非public属性)
Constructor getDeclaredConstructors() 返回该类中所有的构造函数数组(不分public和非public属性)
四种获取成员方法的方法
Method getMethod(String name, Class[] params) 根据方法名和参数,返回一个具体的具有public属性的方法
Method[] getMethods() 返回所有具有public属性的方法数组
Method getDeclaredMethod(String name, Class[] params) 根据方法名和参数,返回一个具体的方法(不分public和非public属性)
Method[] getDeclaredMethods() 返回该类中的所有的方法数组(不分public和非public属性)
四种获取成员属性的方法
Field getField(String name) 根据变量名,返回一个具体的具有public属性的成员变量
Field[] getFields() 返回具有public属性的成员变量的数组
Field getDeclaredField(String name) 根据变量名,返回一个成员变量(不分public和非public属性)
Field[] getDelcaredField() 返回所有成员变量组成的数组(不分public和非public属性)
希望本文所述对大家java程序设计有所帮助。
原文链接:http://www.cnblogs.com/zhaoyanjun/p/6074887.html