Java反射机制及简单实现
程序员文章站
2022-05-28 19:15:23
...
1、什么是Java的反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。(定义来自网络书籍)
2、Java反射中用到的几个对象
在反射实现中主要用到的几个对象Class、Constructor、Field、Method
2.1 Class:对于任何一个你想操作的类对象,首先都须要将它转化成一个CLass对象然后通过一些JDK的API才能进行进一步的操作。
获得Class对象有三种方法:
2.2 Constructor:帮名思义,此对象是用来获取及操作目标对象的构造方法(包括有参和无参的)
获取Constructor对象:
2.3 Field:用于对目标对象的属性操作
获取Field对象:
2.4 Method对象:此对象是用于获取目标类的方法及其相关的操作
获取Field对象
3、关于反射的简单实现代码(可参考)
3.1 目标对象
3.2 获取Class对象
3.3 对构造方法Constructor的操作
3.4 对Field的操作
3.5 对Method的简单操作
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。(定义来自网络书籍)
2、Java反射中用到的几个对象
在反射实现中主要用到的几个对象Class、Constructor、Field、Method
2.1 Class:对于任何一个你想操作的类对象,首先都须要将它转化成一个CLass对象然后通过一些JDK的API才能进行进一步的操作。
获得Class对象有三种方法:
// 1、通过类来获得Class对象 Class<?> clazz1 = Person.class; // 2、通过Class.forName(含包路径的类类)获得Class对象; Class<?> clazz2 = Class.forName("com.leiht.reflect.Person"); // 3、通过类类的一个实例.getClass()获得Class对象 Class<?> clazz3 = new Person().getClass();
2.2 Constructor:帮名思义,此对象是用来获取及操作目标对象的构造方法(包括有参和无参的)
获取Constructor对象:
// 使用无参/默认构造器创建对象实例 Class<?> clazz = Person.class; Person person = (Person) clazz.newInstance(); System.out.println(person); //通过Constructor对象实现对构造方法的反射 //如果构造方法为private(单例模式)则用getDeclaredConstructor(...)方法 Constructor<Person> con = (Constructor<Person>) clazz.getConstructor(int.class, String.class, int.class);
2.3 Field:用于对目标对象的属性操作
获取Field对象:
//通过字段名获取公有字段 Field f1 = clazz.getField("id");
2.4 Method对象:此对象是用于获取目标类的方法及其相关的操作
获取Field对象
//通过类类的一个实例.getClass()获得Class对象 Class<?> clazz = person.getClass(); Method m = clazz.getMethod("getAge"); int age = (int) m.invoke(person); ·
3、关于反射的简单实现代码(可参考)
3.1 目标对象
package com.leiht.reflect; public class Person { private static String TAG = "Tag"; public int id; private String name; private int age; public Person() { } public Person(int id, String name, int age) { super(); this.id = id; this.name = name; this.age = age; } public int sum(int...numbers) { if (numbers.length==0) return -1; int total = 0; for (int n : numbers) total += n; return total; } public static String getTAG() { return TAG; } public static void setTAG(String tAG) { TAG = tAG; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { // TODO Auto-generated method stub return this.id + this.name + this.age; } }
3.2 获取Class对象
package com.leiht.reflect; import com.leiht.reflect.util.ToStringUtil; /** * 取得Class对象的三种方法 * * @author Leiht * */ public class ReflectClass { public static void main(String[] args) throws Exception { // 1、通过类来获得Class对象 Class<?> clazz1 = Person.class; // 2、通过Class.forName(含包路径的类类)获得Class对象; Class<?> clazz2 = Class.forName("com.leiht.reflect.Person"); // 3、通过类类的一个实例.getClass()获得Class对象 Class<?> clazz3 = new Person().getClass(); // 三种方式获得的Class对象均是相同的,返回true System.out.println(clazz1 == clazz2); System.out.println(clazz2 == clazz3); System.out.println(ToStringUtil.toString(new Person(1000, "雷洪太", 26))); } }
3.3 对构造方法Constructor的操作
package com.leiht.reflect; import java.lang.reflect.Constructor; public class ReflectConstructor { public static void main(String[] args) throws Exception { // 使用无参/默认构造器创建对象实例 Class<?> clazz = Person.class; Person person = (Person) clazz.newInstance(); System.out.println(person); //通过Constructor对象实现对构造方法的反射 //如果构造方法为private(单例模式)则用getDeclaredConstructor(...)方法 Constructor<Person> con = (Constructor<Person>) clazz.getConstructor(int.class, String.class, int.class); Person p = con.newInstance(100,"lisi",29); System.out.println(p); } }
3.4 对Field的操作
package com.leiht.reflect; import java.lang.reflect.Field; import java.lang.reflect.Modifier; public class ReflectField { public static void main(String[] args) throws Exception { Person person = new Person(100, "zhangsan", 18); //通过类类的一个实例.getClass()获得Class对象 Class<?> clazz = person.getClass(); //通过字段名获取公有字段 Field f1 = clazz.getField("id"); //Field对象 System.out.println(f1); //通过Field和person实例取值 Object obj1 = f1.get(person); System.out.println(obj1); //取得私有字段 Field f2 = clazz.getDeclaredField("name"); System.out.println(f2); f2.setAccessible(true); Object obj2 = f2.get(person); System.out.println(obj2); Field f3 = clazz.getDeclaredField("age"); System.out.println(f3); f3.setAccessible(true); f3.set(person, 20); Object obj3 = f3.get(person); System.out.println(obj3); System.out.println(person.getAge()); //获取静态字段 Field f4 = clazz.getDeclaredField("TAG"); System.out.println(f4); //判断是否为静态字段 System.out.println("该字段是否是静态字段" + Modifier.isStatic(f4.getModifiers())); f4.setAccessible(true); System.out.println(f4.get(null)); System.out.print("设置 : "); f4.set(null, "new value"); System.out.println(Person.getTAG()); } }
3.5 对Method的简单操作
package com.leiht.reflect; import java.lang.reflect.Method; public class ReflectMethod { public static void main(String[] args) throws Exception { Person person = new Person(100, "zhangsan", 18); //通过类类的一个实例.getClass()获得Class对象 Class<?> clazz = person.getClass(); Method m = clazz.getMethod("getAge"); int age = (int) m.invoke(person); System.out.println(age); Method setMethod = clazz.getMethod("setAge", int.class); setMethod.invoke(person, 28); System.out.println(person.getAge()); Method arrayMethod = clazz.getDeclaredMethod("sum", int[].class); int result = (Integer) arrayMethod.invoke(person, new int[]{1,2,3}); System.out.println(result); } }