(反射)类的加载(33)
1、类的加载过程:加载、连接、初始化。
2、类的加载:将.class文件加载到内存中,并为之生成对应的class对象。
3、JRE System Librarys :运行时期 系统的类库。
4、java的反射机制:动态获取类的信息和动态调用类的方法的功能。
5、接口是个好东西,因为他可以约束实现接口的类的方法。
6、获取Class文件对象的三种方式(三种方式获取的Class都是同一个,也就是唯一性的):对象获取,类名获取,Class类的静态方法获取(Class = Class.forName("com.taobao.demo.Person"))。 // 注意Stirng 参数是带着包名走 =>即:包名.类名
7、Constructor:是 描述构造方法的对象类,返回值是类的构造器数组 Contructor[] //注意:带private的方法不会返回。
8、关键字权限 ===》public : 外包都能用(最高权限) default:本包内能用。 protected :子类专用。 private :只能自己用。
9、反射泛型擦除(编译后的class文件没有泛型的限制,所以可以add其他类型的数据)
//反射泛型擦除-黑技术,该数组array不能遍历,主要作用是用于理解反射这个技术 ArrayList<String> array = new ArrayList<String>(); array.add("a"); Class c5 = array.getClass(); Method method5 = c5.getMethod("add", Object.class); method5.invoke(array, 200); method5.invoke(array, 500); method5.invoke(array, 1500); System.out.println(array);
10、反射通过配置文件运行的实现:
import java.io.FileReader; import java.lang.reflect.Method; import java.util.Properties; public class Test { public static void main(String[] args) throws Exception{ FileReader file = new FileReader("config.properties"); Properties pr = new Properties(); pr.load(file); file.close(); String className = pr.getProperty("className"); String methodName = pr.getProperty("methodName"); Class c = Class.forName(className); Object obj = c.newInstance();//实例 Method m = c.getMethod(methodName); m.invoke(obj); } }
//config.properties 配置文件
#className=com.taobao.demo2.Student #methodName=study
#className=com.taobao.demo2.Person
#methodName=eat
className=com.taobao.demo2.Worker
methodName=job
package com.taobao.demo2; public class Student { public void study(){ System.out.println("学生在学习"); } }
11、
package com.taobao.demo1; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; public class ReflectDemo { public static void main(String[] args) throws Exception{ Class c1 = Class.forName("cn.itcast.demo1.Person"); // Constructor[] c = c1.getConstructors(); // for(Constructor con : c){ // System.out.println(con); // } //运行空参构造方法 Constructor c = c1.getConstructor(); Object obj = c.newInstance(); Person p = (Person)obj; // System.out.println(obj.toString()); // p.eat(); //通过反射,获取有参数的构造方法并运行 Constructor chave = c1.getConstructor(String.class,int.class); Object obj_have = chave.newInstance("何",25); //System.out.println(obj_have); //反射获取构造方法并运行,有快捷点的方式 //前提: //被反射的类,必须具有空参构造方法 // 构造方法权限 必须是 public // 666 直接创建被反射类的对象实例。 Class c2 = Class.forName("cn.itcast.demo1.Person"); Object obj2 = c2.newInstance(); //反射获取私有的构造方法运行 //不推荐,因为破坏了程序的封装性、安全性 Class c3 = Class.forName("cn.itcast.demo1.Person"); Constructor con3 = c3.getDeclaredConstructor(int.class, String.class); //暴力反射技术:打破封装性。即运行时期,取消java访问权限检查 con3.setAccessible(true); Object obj3 = con3.newInstance(18,"里斯"); //System.out.println(obj3); Class c4 = Class.forName("cn.itcast.demo1.Person"); Object obj4 = c4.newInstance(); Field field = c4.getField("name"); // for(Field f: field){ // System.out.println(f); // } field.set(obj4,"王五"); System.out.println(obj4); Method method = c4.getMethod("eat"); method.invoke(obj4); //反射泛型擦除-黑技术,该数组array不能遍历,主要作用是用于理解反射这个技术 ArrayList<String> array = new ArrayList<String>(); array.add("a"); Class c5 = array.getClass(); Method method5 = c5.getMethod("add", Object.class); method5.invoke(array, 200); method5.invoke(array, 500); method5.invoke(array, 1500); System.out.println(array); } }