反射机制:
要他有啥用,因为反射可以操作字节码文件,反射相关的类就在java.lang.reflect.*包下
拿到字节码文件的三种方式:
方式一 Class.forName() Class类的静态方法。Class类在java.lang包下
Class c1=Class.forName("java.lang.String")
// c1就是String.class文件
方式二 对象.getClass() 每一个对象都有getClass()方法是因为老祖宗object自带基因
String s="abc" Class x=s.getClass() //x也代表String.class文件
那我们输出这么一行代码呢
System.out.println(c1==x) ==判断的是对象的内存地址,结果为true
分析原因,看内存图,字节码文件加载到JVM中,之会装载一份
方式三 任何类型.class java中任何一种类型,包括基本数据类型,都有.class属性
Class z=String.class; Class f=int.class;
那拿到这个字节码文件有什么用呢
一、调newInstance()创建对象
相比于new 一个对象,用反射创建对象加灵活。要注意的是使用newInstance()的前提是这个类有无参构造方法,没有的话就会报实例化异常InstantiationException。就这?等等,反射肯定还有别的作用。
二,还记得Field这个类吗(java.lang.reflect.Field)
准备工作,准备一个类Student,我们的目标是通过反射获取属性的修饰符,属性的类型,属性的名称。是不是有点不可思议啊
这一块用老师的话来说就是查帮助文档,不难
在这之前,先搞清什么是Field对象
我简单说几个方法
拿到Student的字节码文件studentClass之后: Field[] fields =studentClass.getFields() //获取所有public修饰的属性 Field[] fs=studetClass.getDeclareFields() //拿到Student类所有属性,不管访问修饰符是什么都拿得到
拿到Field对象怎么拿属性的名称,属性的类型,属性的访问修饰符呢
拿属性名称 field.getName()
拿属性类型 field.getType()
拿属性修饰符 field.getModifiers()
Field属性反编译原理先来看一段我们能看得懂的代码,
别慌,上面的代码是我们上面讲过的那些方法,可是这段代码还真是神奇的很,看了输出你就一目了然。你给我一个.class文件,我能用上面那段代码拿到你java的原代码。
包括但不限于Java.lang.String,java.lang.Thread
那能不能用反射给对象的属性赋值呢,当然能。
而且spring框架底层就是用这种方式实现的,不要怕,瞄一眼,反现你好像真的能看得懂,再联想一下
noField.set(obj,22222) //给obj这个对象的属性no赋值22222 用老师的话说,这行代码很诡异。
但你是这么获取name属性就会报错,因为name是私有的
你得这么来,打破封装,这也是反射的缺点,给不法分子留下了机会
下图红色框就是打破封装的代码,一行足以



