反射

1.类的加载:创建字节码class文件(类的加载器)-->进方法和数据共享区-->扫描静态方法和main方法-->方法进栈-->变量进堆
2.加载:class文件进入内存并为之创建一个class对象;任何类在使用时都会为其创建一个calss对象
3.连接:验证 是否有正确的内部结构,并和其他类协调一致; 准备 负责为类的静态成员分配内存,并设置默认初始化值 解析 将类的二进制数据中的符号引用替换为直接引用;就是 :int x=1;int sum=x+1转成int sum=1+3
4.初始化:就是平时的初始化步骤;
5.类的初始化可分为:1.创建类的实例2.类的静态变量或者为静态变量赋值3.类的静态方法4.使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
5.初始化某个类的子类6.直接使用java.exe命令来运行某个主类;就是在类里面写一个main方法只有是用到这个类就会初始化
6.根类加载器:BootstrapClassLoader; 扩展类加载器:ExtensionClassLoader; 系统类加载器:SerystemClassLoad
7.反射(又叫解刨):私有的属性和方法都能拿得到;
8.反射一个类需要先得到这个类的字节码class文件对象,反射使用就是这个类中的方法,所以要获取到每一个字节码文件对应的class文件对象
9.Class类就是class文件对象;继承:子类不能继承父类的私有属性和方法
10.获取字节码对象:
构造代码块是new一个对象调用一次,静态代码块是随着类的加载只调用一次
1.通过对象获取字节码文件:Class c1=new Person().getclass();/new Person()因为是空参构造所以打印:公共空参构造;这里还调用了c1的toString()方法:classcom.oracle.demo02.Person
2.通过class属性获取字节码文件对象: Class c2=Person.class; 如果c1==c2是true;因为字节码文件只有一个所以地址不会改变,所以c1和c2是同一个地址
3.通过完整的包名+类名获取:Class c3=Class.forName("com.oracle.demo02.Person");(这里面放地址)
4.反射获取构造方法:1.先获取类的字节码对象:Class c=Person.class;2.获取所有的公共构造函数:Constructor[] con=c.getConstructors();.getConstructors得到的是一个数组
3.遍历:for(Constructor cons:con){system.out.println(cons)};
获取所以构造方法包含私有的:Constructor[] cons=c.getDeclaredConstructors();for(Constructor cons:con){system.out.println(cons)}
5.获取有参的构造函数:Class c=person.class;Constructor cons=c.getConstructor(String.class,int.class);Object obj=c.newInstance("小红",18);system.out.println(obj)
获取私有的有参构造:Constructor cons=c.getDeclaredConstructor(String.class,int.class);爆力破除cons.setAccessible(true);用对象接:Object obj=cons.newInstance (18,"小明");快速创建对象:Object obj=c.newInstance();
6.反射获取成员变量:Class c=Person.class;Field f=c.getField("name");Object obj=c.newInstance();f.set(obj,"熊大");system.out.println(objs);
获取所有的包含私有的成员变量:Class c=Person.class;Field f=c.getDeclaredField("name"); f.setAccessible(true);Object obj=c.newInstances();f.set(obj,"小红");
7.获取公共有参的方法:Class c=Person.class;Method m=c.getMethod("sleep",String.class);Person p=(Person)c.newInstance();m.invoke(p,"小红帽");
获取所有的包含私有的成员方法:Class c=Person.class; Method m=c.getDeclaredMethod("sleep",String.class);m.setAccessible(true);Person p=(Person)c.newInstance();
m.invoke(p,"小红帽");
7.泛型擦除:ArrayList<Integer> arr=new ArrayList<Integer>();正常:arr.add(1);泛型擦除(存String):1.获取字节码文件对象:Class c=arr.getClass();
2.获取添加数据的add方法:Method m=c.getMethod("add",Object.class);m.invoke(arr,"aaa");system.out.println(arr)
//因为泛型不进class文件所以才能用class对象进行反射调用add方法,进行泛型擦除,实际上就是越过了泛型直接写进class文件;
8.利用反射和Properties文件创建可替换的config文件:1.明确数据源:FileReader fr=new FileReader("src/com/oracle/demo03/config.properties")
2.创建properties文件对象:Properties pro=new Properties();3.将文件中的键值对存到集合中:pro.load(fr);4.从集合中获取类名:String classname=pro.getProperty(classname);
5.从集合中获取方法名:String methodname=pro.getProperty(methodname);6.获取该类的字节码文件:Class c=Class.forname(classname);
7.获取方法:Method m=c.getMethod(methodname);Object obj=c.newInstence();m.invoke(obj)

原文地址:https://www.cnblogs.com/hankai2735/p/11481901.html