反射是一项底层技术,相当牛逼!
    课程前半段没感觉到它有多牛逼,
    只是认为它只是用来描述类的对象。

    在后半段的课程中,通过反射的方法居然可以操作修改私有属性,就觉得有点强大的不要不要的了。

    白板笔记本:
    类是用来描述一组对象的,反射机制是用来描述一组类的,
    每一个类都有属性、方法、构造方法,
    每一个类都有权限修饰符、特征修饰符,
    所有的类也具有相同的特征。

    【类型】 【作用】
    Class 用来描述类本身
    Package 用来描述类所属的包
    Field 用来描述类中的属性
    Method 用来描述类中的方法
    Constructor 用来描述类中的构造方法
    Annotation 用来描述类中的注解,例如:@Override

    关于注解,拓哥提了一嘴:

    —-注解可以放在类、属性、方法、构造方法上面
    —-注解可以放在参数前面

    ———思考的问题———如何获取Class?———
    1、通过这三个方法来获取:
    ① Class clazz = Class.forName(“包名.类名”); (String类型的参数)
    通过类的全名**来获取当前的类
    ② Class clazz = 类名.class;
    它是属性,调取的是关键字例如:person.class;
    类名必须存在**
    ③ Class clazz = 对象.getClass();
    通过对象.getClass,它是Object类中的方法,
    每个引用类型都有这个方法。

    2.Class中的常用方法
    int result = getModifiers();
    用来获取类的修饰符(权限 特征),返回值是int类型
    每一个修饰符用一个整数来进行表示

    从0开始—>1、2、4、8、16、32、64、128、256、512、1024、2048
    0—>表示默认不写 1—>表示public 2—>表示private
    4—>表示protected 8—>表示static 16—>表示final
    32—>表示synchronized 64—>表示volatile 128—>表示transient
    256—>表示native 512—>表示interface 1024—>表示abstract
    1. String name = getName(); --->获取类全名(包含包名)<br /> String simpleName = getSimpleName(); --->获取类名<br /> Package p = getPackage(); --->获取包名<br />p.getName(); <br /> Class sclazz = getSuperClass(); --->获取超类(父类)<br /> Class[] classes = getInterface(); --->用来获取当前clazz的所有父接口<br /> Object obj = newInstance(); --->默认调用无参数构造方法来创建对象<br /> Field f = getField("属性名"); --->只能获取的名字是已知的<br /> Field[] fs = getFields(); --->可以获取包括继承关系的全部属性的名字<br /> 这两个方法只能获取公有的属性,但可以获取继承过来的父类属性<br /> getDeclaredField("属性");<br /> Field[] fs = getDeclaredFields();<br /> 这两个方法能获取公有的和私有的属性,但只能获取本类中的属性

    3.Field类中的常用方法

    【返回值】 【赋值】 【方法名】
    int = getModifers()
    Class = getType()
    String = getName()

    操作属性,向里面存值:set(对象,值) —>存的是对象和值
    操作属性,从里面取值:值 = get(对象) —>参数是个对象,返回的是值
    setAccessable(true); 可以修改属性被操作

    对象 = new();//创建对象空间,当前对象空间里有自己的一套元素(属性、方法)
    对象.属性 = 值;
    属性 = 类.getField();
    属性.赋值(哪个对象,值);
    值 = 对象.属性 值 = 属性.取值(哪个对象)

    4.通过一个小应用演示反射reflect可以操作并且修改String类的值value

    1. package testreflect;
    2. import java.lang.reflect.Field;
    3. public class ChangeStringValue {
    4. public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
    5. String str = new String("abc");
    6. System.out.println(str);
    7. //反射的技术,可以获取私有属性,且可以操作它
    8. //1.想要操作属性,必须先获取String类对应的Class
    9. Class clazz = str.getClass();
    10. //2.通过clazz获取类中的Value属性
    11. Field field = clazz.getDeclaredField("value"); //field表示String类下的属性
    12. //3.不能直接操作属性的值,必须先将私有属性设置为可被操作
    13. field.setAccessible(true);
    14. //属性原本是 final修饰的 char[]数组 的value --> private final char[] value = {'a','b','c'};
    15. //4.获取value属性里面的值,它是数组,所以里面存的是一个内存地址@AOI783之类的东西.
    16. //我们不修改地址,但要修改地址对应的字符,所以要获取内存地址
    17. char[] temp = (char[])field.get(str);
    18. //5.通过temp的地址引用,找到真实String对象中的数组,去修改数组内的每一个元素
    19. temp[0] = '张'; temp[1] = '三'; temp[2] = '哥';
    20. //6.最终输出一个str的值
    21. System.out.println(str);
    22. }
    23. }

    ——————输出结果——————
    image.png

    思考:反射机制这么强大,它甚至可以修改String类型的值,
    那么是不是可以修改支付系统的签名串?把未支付变成已支付?