javaSE传智博客视频学习笔记————反射
内容
- 反射是什么
- 类加载器
- 获取反射的Class对象
- 获取反射的构造方法
- 创建对象
- 获取反射的成员变量
- 获取反射的方法
- 泛型的擦除
- 反射的应用———使用properties配置文件来运行反射方法
-
反射是什么
反射就是在运行中可以获得类的各种信息,如成员变量,方法等。
-
类加载器
类加载器就是可以将 .class 文件加载到内存中,生成对应的Class对象。
-
获取反射的Class对象
方法一:通过Object类中的getClass()方法
Person p = new Person();
Class c = p.getClass();
方法二:直接 类.Class 来获取(任意的数据类型都有class的静态属性)
Class c2 = Person.class;
方法三:通过Class类中forName的方法
Class c3 = Class.forName("cn.it.getclass.Person");
forName中的参数是类的全名,可以通过 右键类名》Copy Qualified Name 来复制类名
在到需要的地方粘贴即可。
-
获取反射的构造方法
- 获得所有的构造方法(先获得Class然后getConstructors()返回构造方法的数组):
Class c1 = Class.forName("cn.it.getclass.Person"); Constructor [] cons = c1.getConstructors(); for( Constructor c :cons){ System.out.println(c); }
- 获得指定的构造方法(根据getConstructor()中的参数来判断,例如:如果没有填参数就返回空参构造方法):
Class c1 = Class.forName("cn.it.getclass.Person"); Constructor cons =c1.getConstructor(String.class); System.out.println(cons);
注意:参数是class类型的
-
创建对象
创建一个对象必须要先获得一个构造方法
//获取class对象
Class c = Class.forName("cn.it.getclass.Person");
//获取一个构造方法(这里的构造是带String类型参数的方法)
Constructor cons = c.getConstructor(String.class);
//创建一个对象 参数是带给 构造方法 相当于 new Person("小名")
Object obj = cons.newInstance("小名");
-
获取反射的成员变量
- 获取所有的变量
Class c = Class.forName("cn.it.getfield.Person"); Field [] fields =c.getFields(); for(Field f :fields){ System.out.println(f); }
- 获取指定的变量 ,变量名字为age
Class c = Class.forName("cn.it.getfield.Person"); Field f = c.getField("age"); System.out.println(f);
- 给变量赋值
-
Class c = Class.forName("cn.it.getfield.Person"); Constructor con = c.getConstructor(String.class); Object obj = con.newInstance("小明"); //获取变量name Field nameField = c.getField("name"); //赋值 nameField.set(obj,"小红");
此时的名字已经不是小明了,而是小红。
-
赋值的时候,是用set()方法,第一个参数是赋值的对象,第二个是值。
-
获取反射的方法
- 获取方法(这里获取了两个方法一个无参,一个有参(参数是String类型的))
Class c = Class.forName("cn.it.getMethod.Person"); Method method1 = c.getMethod("method1"); Method method4 = c.getMethod("method4",String.class);
- 使用方法
第一步:获类,获构造,建对象
第二步:获得方法
第三步:使用方法
//第一步
Class c = Class.forName("cn.it.getMethod.Person");
Constructor con = c.getConstructor(String.class);
Object obj = con.newInstance("小明");
//第二步
Method method1 = c.getMethod("method1");
Method method4 = c.getMethod("method4", String.class);
//第三步
Object result1 = method1.invoke(obj);
Object result4 = method4.invoke(obj, "喂喂喂喂喂喂");
-
泛型的擦除
泛型擦除 是什么 例如:
ArrayList<Integer>是无法往里边插入String或者其他的类型的数据的
但是使用泛型擦除的话就可以往里边插入其他类型的数据了,
所以Integer这个泛型约束就不起作用了
所以就叫做泛型擦除
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(new Integer(1));
list.add(new Integer(2));
System.out.println(list);
//[1, 2]
Class c = Class.forName("java.util.ArrayList");
//直接获取ArrayList的add(object o)方法
Method add = c.getMethod("add", Object.class);
//直接使用
add.invoke(list, "哈哈哈");
System.out.println(list);
//[1, 2, 哈哈哈]
-
反射的应用———使用properties配置文件来运行反射方法
我们可以看到反射方法中的参数大多是String类型的,那我们就可以把参数放入文本文件中,通过io获取了。
第一步:建一个文本名字叫:reflect.properties 后缀是 properties类型的。位置放在第一层目录下。
第二步:
//获取文件
Properties pro = new Properties();
pro.load(new FileReader("reflect.properties"));
//获取类名
String className = pro.getProperty("className");
//获取方法名
String methodName = pro.getProperty("methodName");
//老三样:获取类(此时的类名已经是参数了),获取构造方法,建对象
Class c = Class.forName(className);
Constructor con = c.getConstructor(String.class,int.class,String.class);
Object obj = con.newInstance("小明",22,"中国");
//获取方法。此时的方法名已经是参数了(因为是无参的方法所以是null)
Method m = c.getMethod(methodName, null);
//执行方法
m.invoke(obj, null);