Java的动态性支持学习一 - 反射机制 概念概述
Java的动态性支持学习二 - 反射机制 属性、方法、对象的操作
Java的动态性支持学习三 - 反射机制 取消属性、方法、构造器的访问限制
Java的动态性支持学习四 - 反射调用的性能对比
Java的动态性支持学习五 - 方法句柄 概念和句柄类型
Java的动态性支持学习六 - 方法句柄 获取和调用
Java的动态性支持学习七 - 方法句柄调用的性能对比
这篇博文学习下通过反射操作属性、方法、对象。
属性 Filed
Filed类的对象代表成员变量,携带成员变量的信息,其中有几个重要的方法:
- Object get(Object obj) 返回obj对象的成员变量值,返回的Object类型;
- xxx getXxx(Object obj) 返回obj对象的成员变量值,其中xxx代表8种基本数据类型,返回为指定的数据类型;
- set(Object obj, Object value) 设置obj对象的属性值;
- setXxx(Object obj, xxx value)设置obj对象的属性值,其中xxx代表8种基本数据类型;
- Class getType() 返回Field对象对应的成员变量的类型。如果成员变量为基本类型,则返回的是"<基本数据类型封装名>.TYPE"。
Demo:
package net.oseye; import java.lang.reflect.*; public class ReflectTest { public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{ User user=new User(); user.name="osEye"; Class c=user.getClass(); Field field=c.getDeclaredField("name"); System.out.println(field.get(user)); field.set(user, "kevin"); System.out.println(field.get(user)); } } class User{ public String name; }
输出:
osEye kevin
方法 Method
Method类的对象代表一个方法,携带方法 ,其中最重要的方法是invoke,声明:Object invoke(Object obj, Object... args)
- 不管实际对应的方返回值是什么类型,都返回Object类型。若返回值为基本类型,则返回对应封装类的对象;
- obj参数指出要被调用方法所属的对象,若调用静态方法则用null;
- args是方法的参数序列,若方法没有参数则传递空数组:new Object[0];
Demo:
package net.oseye; import java.lang.reflect.*; public class ReflectTest { public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{ User user=new User(); user.name="osEye"; Class c=user.getClass(); Method mth=c.getDeclaredMethod("SayHello", String.class); mth.invoke(user, "kevin"); } } class User{ public String name; public void SayHello(String name){ System.out.println(this.name+" say to "+name+": 'Hello'."); } }
输出:
osEye say to kevin: 'Hello'.
创建对象 Constructor
Constructor类的对象代表一个构造器,携带构造器的相关信息,其只要方法是newInstance,声明如下:Object newInstance(Object... initargs)
Demo:
package net.oseye; public class ReflectTest { public static void main(String[] args) throws InstantiationException, IllegalAccessException{ Class c=User.class; User user=(User) c.newInstance(); user.name="oseEye"; user.SayHello("kevin"); } } class User{ public String name; public void SayHello(String name){ System.out.println(this.name+" say to "+name+": 'Hello'."); } }
输出:
oseEye say to kevin: 'Hello'.
顺便提下,数组比较特殊,它没有提供构造器,因此不能通过Class或Constructor类的newInstance方法创建数组,但可以使用java.lang.reflect.Array类中提供了动态创建数组的newInstance方法,如果需要可自行查看。