zoukankan      html  css  js  c++  java
  • Java的反射机制

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性
    Java本身是一种静态语言 , 不能够在运行期改变程序结构和变量类型
    但是反射机制是一种十分重要的动态特性

    实现示例
    首先定义一个类

     1 class Demo {
     2     private String name;
     3     private int age ;
     4     private Date birth;
     5     private boolean sex ;
     6     //注意 :对于boolean类型属性,IDE自动生成的是名为isXXX的getter方法
     7     public Demo(){}
     8     public Demo(String name, int age, Date birth){
     9         this.name = name;
    10         this.age = age;
    11         this.birth = birth;
    12     }
    13    //getter与setter方法...
    14 
    15 }
    
    

    获取该类中的属性和值

     1 public static void getObjectValue(Object object) throws Exception {
     2     if (object == null) {
     3         //验证是否为null,防止NullPointerException
     4         return;
     5     }
     6     Class<?> clz = object.getClass();
     7     // 获取实体类的所有字段(但不包括继承自父类的)
     8     Field[] fields = clz.getDeclaredFields();
     9     // 执行遍历
    10     for (Field field : fields) {
    11         //拿到该属性的getter方法
    12         Method method = clz.getMethod("get"+ getMethodName(field.getName()));
    13         // 调用getter方法获取属性值
    14         Object val = method.invoke(object);
    15         System.out.println(field.getName()+":" + val);
    16         }
    17     }
    18 
    19     // 把一个字符串的第一个字母大写
    20 private static String getMethodName(String fieldName) {
    21     StringBuilder sb = new StringBuilder(fieldName);
    22     char ch = Character. toUpperCase(fieldName.charAt(0));
    23     sb.setCharAt(0, ch);
    24     return sb.toString();
    25 }
    调用方式
    1 public static void main(String[] args){
    2     Demo demo = new Demo("Loli" ,18,new Date());
    3     try {
    4         getObjectValue(demo);
    5     } catch (Exception e) {
    6         e.printStackTrace();
    7     }
    8 }

    基于这种反射机制的实现 , 我们可以动态获取到任意一个类中所有的属性和方法
    从而可以去开发一些复用性很强的功能函数
    比如把任意一个对象的属性和对应的值放入到一个Map集合当中
    从而方便进行遍历或者数据的传输


    使用反射机制在外部给对象私有属性赋值

    1 public class Cat {
    2     private String name;
    3     public String getName(){
    4         return this.name;
    5     }
    6 }

    这个类没有提供name属性的set方法

     1 try {
     2     Class<Cat> catClass = Cat.class;
     3     Field name = catClass.getDeclaredField("name");
     4     name.setAccessible(true);//取消Java语言访问检查
     5     Cat cat = (Cat) catClass.newInstance();
     6     name.set(cat, "abc");
     7     System.out.println(cat.getName());
     8 } catch (IllegalAccessException e) {
     9     e.printStackTrace();
    10 } catch (InstantiationException e) {
    11     e.printStackTrace();
    12 } catch (NoSuchFieldException e) {
    13     e.printStackTrace();
    14 }

    在Field对象上调用set方法可以修改一个对象的属性
    需要注意的是 , 必须调用setAccessible取消Java语言的访问检查 , 否则是无法给私有属性赋值的

    同理 , 在Field对象上调用get方法可以获取指定对象的这个属性的值

    可以想到Spring框架当中的 @Autowired 自动注入 , 即使是私有属性 , 没有提供set方法也可以注入
    应该就是基于这种机制去实现的 

  • 相关阅读:
    《乘法运算定律》
    pytest(三十九)--内置request读取项目的根目录 rootdir
    《乘除法意义及各部分关系》
    《比例尺》
    《百分数》
    《8的乘法口诀》
    《1升有多少》
    ant-design-vue 上传图片组件
    ant-design-vue快速搭建
    js实现无缝滚动
  • 原文地址:https://www.cnblogs.com/programInit/p/6363068.html
Copyright © 2011-2022 走看看