查看: 59|回复: 3

[学习经验&经历] 我们来聊聊JAVA反射?

[复制链接]
  • TA的每日心情

    2018-10-18 16:49
  • 签到天数: 13 天

    [LV.3]偶尔看看II

    发表于 2019-7-4 14:45:22 | 显示全部楼层 |阅读模式
    本帖最后由 青衫忆笙 于 2019-7-4 14:48 编辑

    什么是反射?
    [color=rgba(2, 0, 0, 0.6)]JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
    [color=rgba(2, 0, 0, 0.6)]要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

    反射机制的作用
    • 反编译 : .class->.java

    • 通过反射机制访问java对象的属性,方法,构造方法等;


       这样应该更容易理解

    我们来看看sun给我提供的反射机制的类
    1. java.lang.Class;               

    2. java.lang.reflect.Constructor;

    3. java.lang.reflect.Field;        

    4. java.lang.reflect.Method;

    5. java.lang.reflect.Modifier;
    复制代码

    [color=rgba(2, 0, 0, 0.6)]很多反射中的方法,属性操作我们都可以从这四个类中查询。还是那句话要学着不断查询Api,那才是最好的方法

    具体怎么用的呢?

      1. 反射机制获取类有三种方法,我们来获取user类型
      复制代码


    1. //第一种方式:
    2. Classc1 = Class.forName("User");
    3. //第二种方式:
    4. //java中每个类型都有class 属性.
    5. Classc2 = User.class;

    6. //第三种方式:
    7. //java语言中任何一个java对象都有getClass 方法
    8. User user = new User();
    9. Class c3 = user .getClass(); //c3是运行时类 (user 的运行时类是User)
    复制代码

    [color=rgba(2, 0, 0, 0.6)]2.创建对象:获取类以后我们来创建它的对象,利用newInstance();
    1. Class c =Class.forName("User");
    2. //创建此Class 对象所表示的类的一个新实例
    3. Objecto = c.newInstance(); //调用了User的无参数构造方法.
    复制代码

    [color=rgba(2, 0, 0, 0.6)]3.获取属性:分为所有属性和指定的属性:a,先看获取所有的属性的写法:
    1. //获取整个类
    2. Class c = Class.forName("java.lang.Integer");
    3. //获取所有的属性?
    4. Field[] fs = c.getDeclaredFields();
    5.          
    6. //定义可变长的字符串,用来存储属性
    7. StringBuffer sb = new StringBuffer();
    8. //通过追加的方法,将每个属性拼接到此字符串中
    9. //最外边的public定义
    10. sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() +"{\n");
    11. //里边的每一个属性
    12. for(Field field:fs){
    13.     sb.append("\t");//空格
    14.     sb.append(Modifier.toString(field.getModifiers())+" ");//获得属性的修饰符,例如public,static等等
    15.     sb.append(field.getType().getSimpleName() + " ");//属性的类型的名字
    16.     sb.append(field.getName()+";\n");//属性的名字+回车                               
    17. }       
    18. sb.append("}");
    19.        
    20. System.out.println(sb);
    复制代码

    [color=rgba(2, 0, 0, 0.6)]b,获取特定的属性,对比着传统方法来学习:
    1. public static void main(String[] args) throws Exception{
    2.                        
    3.         //以前的方式:
    4.         /*
    5.         User u = new User();
    6.         u.age = 12; //set
    7.         System.out.println(u.age); //get
    8.         */
    9.                        
    10.         //获取类
    11.         Class c = Class.forName("User");
    12.         //获取id属性
    13.         Field idF = c.getDeclaredField("id");
    14.         //实例化这个类赋给o
    15.         Object o = c.newInstance();
    16.         //打破封装 无视访问级别
    17.         idF.setAccessible(true); //使用反射机制可以打破封装性,导致了java对象的属性不安全。
    18.         //给o对象的id属性赋值"110"
    19.         idF.set(o, "110"); //set
    20.         //get
    21.         System.out.println(idF.get(o));
    22. }
    复制代码

    [color=rgba(2, 0, 0, 0.6)]4.获取方法和构造方法,不在详细描述,来看一下方法api:
    方法作用
    getDeclaredMethods()获取所有的方法
    getReturnType()获得方法的返回类型
    getParameterTypes()获得方法的传入参数类型
    getDeclaredMethod("方法名",参数类型.class,……)获得特定的方法
    getDeclaredConstructors()获取所有的构造方法
    getDeclaredConstructor(参数类型.class,……)
    获取特定的构造方法
    getSuperclass()获取某类的父类
    getInterfaces()获取某类实现的接口
    [color=rgba(2, 0, 0, 0.6)]这样我们就可以获得类的各种内容,进行了反编译。对于JAVA这种先编译再运行的语言来说,反射机制可以使代码更加灵活,更加容易实现面向对象。

    [color=rgba(2, 0, 0, 0.6)]综上为,JAVA反射的初次学习,灵活的运用它,能够使我们的代码更加灵活,但是它也有它的缺点,就是运用它会使我们的软件的性能降低,复杂度增加,所以还要我们慎重的使用它。
  • TA的每日心情
    难过
    2015-12-18 11:33
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2019-7-18 21:51:51 | 显示全部楼层
    什么是反射?
    您需要登录后才可以回帖 登录 | 注册青鸟豆号

    本版积分规则

    Copyright 1999-2019 Beijing Aptech Beida Jade Bird Information Technology Co.,Ltd

    北大青鸟IT教育 北京阿博泰克北大青鸟信息技术有限公司 版权所有

    京ICP备11045574号-3 京公网安备11010802013845号

    快速回复 返回顶部 返回列表