又把反射给忘了,没办法,再学习一遍吧。
一、什么是反射?
反射机制是指在运行状态,对于任意一个类,可以知道这个类的所有属性和方;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。
二、与反射相关的几个类
- java.lang.Class : 代表一个类
- java.lang.reflect.Method : 代表类的方法
- java.lang.reflect.Field : 代表类的成员变量
- java.lang.reflect.Constructor : 代表类的构造方法
- java.lang.reflect.Modifier : 修饰符
三、本人初学反射时学到的几句话
我们创建了一个类,通过编译( javac.exe ) 生成对应的 .class(字节码) 文件,然后通过 java.exe( JVM的类加载器来完成 )加载此 .class 文件,此 .class 文件加载到内存以后,就是一个运行时类,存放在缓存区,这个运行时类本身就是一个Class的实例。
java.lang.Class是反射的源头。
四、获取Class实例的四种方法
1、类名.class
2、实例.getClass()
3、Class.forName("java.lang.String") # 全包名.类名
4、使用 类加载器
ClassLoader classLoader = this.getClass().getClassLoader();
Class clazz1 = classLoader.loadClass("java.lang.String"); # 全包名.类名
# code
public class TestReflect {
public static void main(String args[]) {
TestReflect testReflect = new TestReflect();
System.out.println(testReflect.getClass().getName());
// 获取Class对象
try {
Class clazz1 = Class.forName("com.reflect.TestReflect");
System.out.println(clazz1.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Class clazz2 = new TestReflect().getClass();
System.out.println(clazz2.getName());
Class clazz3 = TestReflect.class;
System.out.println(clazz3.getName());
}
}
有了Class的实例我们就可以为所欲为了
五、反射的操作
1、创建对象:newInstance()
# 注意:类必须有一个**无参构造器**,和,构造器的访问权限的足够。否则会报错。
2、获取属性
Class clazz = Son.class;
①: Field fields[] = clazz.getFields(); 获取Son类及其父类中的声明为public的属性
②: Field fields1[] = clazz.getDeclaredFields(); 获取Son类中的所有属性
③:Field field_public = clazz.getField(); 获取父类及其本身指定的public的属性
④:Field field_private = clazz.getDeclaredField("");获取其本身指定的属性
Object obj = clazz.newInstance();
// 为属性设置值,属性是依赖于对象的,所以你必须先要有一个对象
field_private.setAccessible(true);
// 为obj对象的XX field设置值
field_private.set(obj, "KD");
// 取出field的值
System.out.println(field_private.get(obj));
3、获取方法
Class clazz = Son.class;
// 获取本类指定的方法[方法名称,参数类型.class]
Method method = clazz.getDeclaredMethod("getSonPrivateGender", String.class);
// 获取本类及其父类声明为public的指定的方法[方法名称,参数类型.class]
Method method1 = clazz.getMethod("getFatherPublicAge", null);
System.out.println(method1);
for (Class pt : method.getParameterTypes()) {
System.out.println("方法参数类型:" + pt);
}
System.out.println(method);
System.out.println();
// 获取父类
System.out.println(clazz.getSuperclass());
// private 的方法必须使用这个方法破坏权限修饰符的局限性
method.setAccessible(true);
// 调用方法,invoke(对象,方法的入参)
method.invoke(obj, "大大");
4、获取构造函数
// 获取本类中指定的构造方法
Constructor constructor = clazz.getDeclaredConstructor(构造函数参数);
Constructor getConstructor(Class[] params)//根据指定参数获得public构造器
Constructor[] getConstructors()//获得本类中 public的所有构造器
Constructor[] getDeclaredConstructors()//获得本类的所有构造器
未完待续……