基本概念
利用Java语言反射机制,可以在运行时对程序进行动态控制,通过反射也可以打破类的包装机制 在Java程序运行过程中,每个类被加载后都在内存中产生一个对应的Class对象,主要包括构造器,方法,成员变量等Java中无论一个类生成多少个对象,这些对象都会对应内存中同一个class对象在JDK中,主要由以下类来实现Java反射机制 Java.lang.Class类 对应类本身 Java.lang.reflect.Field类 对应类中定义的成员变量 Java.lang.reflect.Method类 对应类中定义的方法 Java.lang.reflect.Constructor类 对应类中定义构造方法 Java.lang.reflect.Array类 对应如何创建数组,为数组变量赋值,取数组值
获取Class对象的三种方法
方法一:Class的静态方法传入类的全称 Class<?> classType = Class.forName("com.itlwc.MyReflection"); 方法二:Java内置语法 Class<?> classType = MyReflection.class; 方法三:使用对象的getClass() Class<?> classType = new String("abc").getClass();
Class常用方法
package com.itlwc;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;public class Test {public static void main(String[] args) throws Exception {// 返回指定类对应的Class对象,如果找不到指定类抛出ClassNotFoundExceptionClass<?> c = Class.forName("com.itlwc.Test");// 返回Class对象自己定义所有构造器Constructor<?> c1 = c.getDeclaredConstructor();// 返回Class对象自己定义所有构造器Constructor<?>[] c2 = c.getDeclaredConstructors();// 返回Class对象自己定义public构造器Constructor<?> c3 = c.getConstructor();// 返回Class对象自己定义public构造器Constructor<?>[] c4 = c.getConstructors();// 返回Class对象自己定义所有成员变量,不包括父类继承来的成员变量Field f1 = c.getDeclaredField("name");// 返回Class对象自己定义成员变量数组,不包括父类继承来的成员变量Field[] f2 = c.getDeclaredFields();// 返回Class对象自己定义public成员变量,包括父类有访问权限的成员变量Field f3 = c.getField("age");// 返回Class对象自己定义public成员变量数组,包括父类有访问权限的成员变量Field[] f4 = c.getFields();// 返回Class对象自己定义所有成员方法,不包括父类继承来的成员方法Method m1 = c.getDeclaredMethod("getName");// 返回Class对象自己定义成员方法数组,不包括父类继承来的成员方法Method[] m2 = c.getDeclaredMethods();// 返回Class对象自己定义public成员方法,包括父类有访问权限的成员方法Method m3 = c.getMethod("getName");// 返回Class对象自己定义public成员方法数组,包括父类有访问权限的成员方法Method[] m4 = c.getMethods();// Class对象所对应类的名称String str1 = c.getName();// Class对象所对应类所在的包Package p = c.getPackage();// 返回源代码中给出的基础类的简称String str2 = c.getSimpleName();// 返回Class对象表示的实体的超类的ClassClass<?> cc = c.getSuperclass();// Class对象是否为注解类型boolean b1 = c.isAnnotation();// Class对象是否为匿名内部类boolean b2 = c.isAnonymousClass();// Class对象是否为数组类型boolean b3 = c.isArray();// Class对象是否为枚举类型boolean b4 = c.isEnum();// Class对象是否为接口类型boolean b5 = c.isInterface();// Class对象是否为成员内部类boolean b6 = c.isMemberClass();// 创建加载类的对象Test t = (Test) c.newInstance();t.getName();// Class对象转换为字符串String str3 = c.toString();}private String name;public String age;public String getName() {return name;}public void setName(String name) {this.name = name;}public Test() {}public Test(String name) {this.name = name;}private Test(String name, String age) {this.name = name;this.age = age;}}
Field常用方法
package com.itlwc;import java.lang.reflect.Field;class PrivateClass {public String name;public String age;private String password;}public class T {public static void main(String[] args) throws Exception {// 获取Class对象Class<?> clazz = PrivateClass.class;Object obj = clazz.newInstance();// 返回Class对象自己定义public成员变量数组,包括父类有访问权限的成员变量Field[] field = clazz.getFields();for (Field f : field) {// 成员变量名称System.out.println(f.getName());// 成员变量类型System.out.println(f.getType());// 成员变量值System.out.println(f.get(obj));}// 返回Class对象自己定义的私有不带参数方法,名称为method1Field f = clazz.getDeclaredField("password");f.setAccessible(true);System.out.println("成员变量名称: " + f.getName() + " 成员变量类型: " + f.getType()+ " 成员变量值: " + f.get(obj));}}
Method常用方法
package com.itlwc; import java.lang.reflect.Method; class PrivateClass { private void method1() { System.out.println("调用了无参私有方法"); } private String method2(String str, int a) { return "调用了有参私有方法: " + str + "今年" + a + "岁"; } } public class T { public static void main(String[] args) { // 获取Class对象 Class<?> clazz = PrivateClass.class; try { //生成PrivateClass类的一个实例 Object obj= clazz.newInstance(); // 返回Class对象自己定义成员方法数组,不包括父类继承来的成员方法 Method method[] = clazz.getDeclaredMethods(); for (Method m : method) { // 方法名称 m.getName(); // 方法返回值 m.getReturnType(); // 方法参数序列 Class<?>[] c = m.getParameterTypes(); for (Class<?> cc : c) { System.out.println(cc); } } // 返回Class对象自己定义的私有不带参数方法,名称为method1 Method m = clazz.getDeclaredMethod("method1", new Class[] {}); m.setAccessible(true); Object object = m.invoke(obj, null); System.out.println(object); // 返回Class对象自己定义的私有带参数方法,名称为method2 m = clazz.getDeclaredMethod("method2", new Class[] { String.class, Integer.TYPE }); m.setAccessible(true); object = m.invoke(obj, new Object[] { "lwc", 18 }); System.out.println(object); } catch (Exception e) { e.printStackTrace(); } } }
Constructor常用方法
package com.itlwc;import java.lang.reflect.Constructor;class PrivateClass {public PrivateClass() {}private PrivateClass(String str) {System.out.println("私有构造器");}}public class T {public static void main(String[] args) throws Exception {PrivateClass pc = new PrivateClass();// 获取Class对象Class<?> clazz = pc.getClass();// 返回Class对象自己定义所有构造器Constructor<?>[] constructor = clazz.getDeclaredConstructors();for (Constructor<?> cc : constructor) {// 构造器名称System.out.println(cc.getName());// 构造器参数序列 Class<?>[] c = cc.getParameterTypes(); for (Class<?> ccc : c) { System.out.print(ccc); }}}}
利用反射动态创建数组
package com.itlwc;import java.lang.reflect.Array;public class Test {public static void main(String[] args) throws Exception {// 使用反射动态创建长度为5的一维int型数组int[] intArray = (int[]) Array.newInstance(Integer.TYPE, 5);// 使用反射动态创建二维String型数组,一维长度为5,二维长度为4String[][] stringArray = (String[][]) Array.newInstance(String.class,new int[] { 5, 4 });}}