Class类 - 代表类的Class对象 Constructor类-代表类的构造方法 Field类-代表类的属性 Method类-代表类的方法 Array类 - 提供动态创建数组,以及访问数组元素的静态方法 通过前四个对象我们可以粗略的看到一个类的各个组成部分 Array类会在最后有所简述。
Java 反射机制主要提供了以下功能在运行时判断任意一个对象所属的类。 在运行时构造任意一个类的对象。 在运行时判断任意一个类所具有的成员变量和方法。 在运行时调用任意一个对象的方法
代码示例(获取Class对象)
package com.Lct.classtype; public class ClassDemo { public static void main(String[] args) { //使用实例对象.getClass() /*Employee employee = new Employee("zhangsan", 18); Class<?> class1 = employee.getClass(); System.out.println(class1.getName()); System.out.println(class1.getSuperclass().getName());*/ //使用类名.Class /*Class<?> class1 = Employee.class; System.out.println(class1.getName()); System.out.println(class1.getSuperclass().getName());*/ //使用Class.forName("") /*try { Class<?> class1 = Class.forName("com.Lct.classtype.Employee"); System.out.println(class1.getName()); System.out.println(class1.getSuperclass().getName()); } catch (ClassNotFoundException e) { e.printStackTrace(); }*/ //基本数据类型的Class对象 /* Class <?> class1 = int.class; System.out.println(class1.getName()); //基本数据类型没有父类,下面代码会报NullPointerException异常 //System.out.println(class1.getSuperclass().getName()); */ //包装类获取基本数据类型的Class对象 /* Class <?> class1 = Integer.TYPE; System.out.println(class1.getName()); //基本数据类型没有父类,下面代码同样会报NullPointerException异常 //System.out.println(class1.getSuperclass().getName()); */ //获取包装类的Class对象 Class <?> class1 = Integer.class; System.out.println(class1.getName()); System.out.println(class1.getSuperclass().getName()); } } class Employee { private String name; private int age; public Employee(String name, int age) { super(); this.name = name; this.age = age; } 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; } }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属性)
Method getMethod(String name, Class[] params) — 根据方法名和参数,返回一个具体的具有public属性的方法 Method[] getMethods() — 返回所有具有public属性的方法数组 Method getDeclaredMethod(String name, Class[] params) — 根据方法名和参数,返回一个具体的方法(不分public和非public属性) Method[] getDeclaredMethods() — 返回该类中的所有的方法数组(不分public和非public属性)
抽象的文字描述总是没有代码表现的直白,示例代码中有这两个方法的调用,运行后的结果如下:
getDeclaredMethods方法获取的所有方法getMethods方法获取的所有方法修饰符–方法名–返回值类型修饰符–方法名–返回值类型public – toString – class java.lang.Stringpublic – toString – class java.lang.Stringpublic – getName – class java.lang.Stringpublic – getName – class java.lang.Stringpublic – write – voidpublic – write – voidpublic – setName – voidpublic – setName – voidprivate – work – void无法获得work方法public – setAge – voidpublic – setAge – voidpublic – getAge – intpublic – getAge – intpublic – sleep – void (父类公共方法)public final – wait – void (超类公共方法)public final native – wait – void (超类公共方法)public final – wait – void (超类公共方法)public – equals – boolean (超类公共方法)public native – hashCode – int (超类公共方法)public final native – getClass – class java.lang.Class (超类公共方法)public final native – notify – void (超类公共方法)public final native – notifyAll – void (超类公共方法)配合表格再去看API中的注解就事半功倍了。
Note:
子类继承父类,既可以重写父类的方法,一旦重写,通过getDeclaredMethods获得就是子类中重写的方法,不要误以为获得的是父类中的方法。getDeclaredMethod()和getMethod()是通过方法名和参数列表获取指定的方法,所能获取的方法的范围各不相同,上述讨论的情况一致。代码示例
package com.Lct.reflection; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; /** * 测试类 */ public class ReflectionAPIDemo { public static void main(String[] args) throws Exception{ //获取Employee类所关联的Class对象 Class<?> classType = Class.forName("com.Lct.reflection.Employee"); //方法1 //通过反射机制调用无参构造方法来实例化对象 Employee employee = (Employee) classType.newInstance(); System.out.println(employee); System.out.println("----------------------------------"); //方法2 //通过反射机制获取构造方法对象,再通过该对象来实例化Employee类的实例 Constructor<?> ct = classType.getConstructor(new Class[]{}); //直接强制类型转换也是可以的 Object object = ct.newInstance(new Object[]{}); if (object instanceof Employee) { Employee em1 = (Employee) object; System.out.println(em1); } System.out.println("----------------------------------"); //通过反射机制获取带参数的构造方法对象,再通过反对向实例化Employee类的实例 Constructor<?> ct2 = classType.getConstructor(new Class[]{String.class,int.class}); Employee em2 = (Employee) ct2.newInstance(new Object[]{"张三",18}); System.out.println(em2); //<<关于getMethods()和getDeclaredMethods()的区别>> //通过反射机制获取Employee类中的所有方法,包括私有的 Method[] methods = classType.getDeclaredMethods(); for (Method method : methods) { System.out.println(Modifier.toString(method.getModifiers())+"--"+method.getName()+"--"+method.getReturnType()); } System.out.println("----------------------------------"); //通过反射机制获取Employee类和超类中的所有共有方法 Method[] m2 = classType.getMethods(); for (Method m : m2) { System.out.println(Modifier.toString(m.getModifiers())+"--"+m.getName()+"--"+m.getReturnType()); } System.out.println("----------------------------------"); //getMethod方法调用父类的方法 //getDeclaredMethod方法无法调用父类的public方法 Method method2 = classType.getMethod("eat", new Class[]{}); method2.invoke(em2, new Object[]{}); System.out.println("----------------------------------"); //通过反射机制获取指定的方法,包括私有的,并可以调用它 Method method = classType.getDeclaredMethod("work", new Class[]{int.class}); System.out.println(method); //使私有的可以访问 method.setAccessible(true); //方法的调用 method.invoke(em2, new Object[]{3}); System.out.println("----------------------------------"); //通过反射机制获取所有属性,包括私有的 Field[] fields = classType.getDeclaredFields(); for (Field field : fields) { System.out.println(field); } System.out.println("----------------------------------"); //通过反射机制获取指定的属性,包括私有的,并可以改变它 Field field = classType.getDeclaredField("name"); //使私有的可以访问 field.setAccessible(true); String object2 = (String) field.get(em2); System.out.println(object2); field.set(em2, "李四"); System.out.println(em2); System.out.println("----------------------------------"); } } /** * 父类 */ class Person{ public void sleep () { System.out.println("sleeping...."); } @SuppressWarnings("unused") private void eat () { System.out.println("eating...."); } } /** * 接口 */ interface Study { public void write(); } /** * 子类 */ class Employee extends Person implements Study{ private String name; private int age; private Object object; public Employee() { super(); System.out.println("无参构造方法"); } public Employee(String name, int age) { super(); System.out.println("带参数的构造方法"); this.name = name; this.age = age; } 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() { return "Employee: "+"[name: "+this.name+" age: "+this.age+"]"; } @SuppressWarnings("unused") private void work (int num) { System.out.println(num+" Employee -- working..."); } @Override public void write() { System.out.println(" Employee -- writing..."); } }目前很少这么用,个人感觉也是没必要,但是本着存在即合理的原则还是写下来,留个印象。
代码示例
package com.Lct.reflection; import java.lang.reflect.Array; public class reflectionArrayDemo { public static void main(String[] args) throws Exception{ Class<?> class1 = Class.forName("java.lang.String"); //创建一维数组 Object array = Array.newInstance(class1, 9); Array.set(array, 0, "zhangdan"); System.out.println(Array.get(array, 0)); //创建二维数组 Object array2 = Array.newInstance(class1, new int[]{2,3}/*创建2行3列的二维数组*/); Object arrayObj = Array.get(array2, 1); Array.set(arrayObj, 1, "lisi"); System.out.println(Array.get(arrayObj, 1)); } }Android反射机制实现与原理 作者写的巨细靡遗,其中LoadMethod类和升级版的LoadMethodEx类非常值得学习。
Android系统原理与源码分析(1):利用Java反射技术阻止通过按钮关闭对话框 这篇博客是Java反射机制在android中的使用实例,知道可以这样用就好,但不推荐,虽然反射很强大,但是也需谨慎使用。
