• Java的反射机制与泛型擦除


    实现方式
      反编译:.class–>.java
      通过反射机制访问java对象的属性,方法,构造方法等
    涉及类
      java.lang.Class;
      java.lang.reflect.Constructor;
      java.lang.reflect.Field;
      java.lang.reflect.Method;
      java.lang.reflect.Modifier;
    Field
      Java反射中Field用于获取某个类的属性或该属性的属性值

    反射获取类的三种方法

    Class c1 = Class.forName("Book");
    Class c2 = Book.class; // Java中每个类型都有class属性
    Book book= new Book(); // java语言中任何一个java对象都有getClass 方法 
    Class c3 = book.getClass(); // c3是运行时类 (book的运行时类是Book)

    创建对象
    获取类以后我们来创建它的对象,利用newInstance:

    Class c =Class.forName("Book");  
    
    // 创建此Class 对象所表示的类的一个新实例  
    Object o = c.newInstance(); // 调用Book的无参数构造方法. 

    获取所有属性

    Class c = Class.forName("java.lang.Integer"); // 获取整个类  
    Field[] fs = c.getDeclaredFields();  // 获取所有的属性
    StringBuffer sb = new StringBuffer();  // 定义可变长的字符串,用来存储属性
    
    sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() +"{
    ");  // 通过追加的方法,将public定义里边的每一个属性拼接到此字符串中
    for(Field field:fs){  
        sb.append("	"); // Tab  
        sb.append(Modifier.toString(field.getModifiers())+" "); // 获得属性的修饰符,例如public,static等  
        sb.append(field.getType().getSimpleName() + " ");// 属性的类型的名字  
        sb.append(field.getName()+";
    "); // 属性名字+回车换行  
    }  
    sb.append("}");  
    System.out.println(sb); 

    获取指定属性

    Class c = Class.forName("User"); // 获取类  
    Field idF = c.getDeclaredField("id"); // 获取id属性  
    Object o = c.newInstance(); // 实例化这个类赋给o 
    idF.setAccessible(true); // 打破封装 :使用反射机制可以打破封装性,导致了对象的属性不安全。
    idF.set(o, "110"); // set,给o对象的id属性赋值"110" 
    System.out.println(idF.get(o)); // get 

    获取方法和构造方法

    使用反射进行泛型擦除

    package com.test;
     
    import java.lang.reflect.Method;
    import java.util.ArrayList;
     
    public class test_fanxing {
        /**
         * * ArrayList<Integer>的一个对象,在这个集合中添加一个字符串数据,如何实现呢?
         * 泛型只在编译期有效,在运行期会被擦除掉*/
        public static void main(String[] args) throws Exception{
            ArrayList<Integer> list=new ArrayList<>();
            list.add(123);
            list.add(321);
            //list.add( "www"); 将会报错  为了解决这个问题,我们对其add方法进行反射,讲字符串添加进去
            //因为不在编译期 所以泛型无效
            Class clazz=Class.forName("java.util.ArrayList");
            Method m=clazz.getMethod("add",Object.class); //API add(E e) 参数Object
            m.invoke(list,"www");
            System.out.println(list);  //[123, 321, www] 成功反射进来字符串
     
        }
    }
  • 相关阅读:
    SpringBoot非官方教程 | 第九篇: springboot整合Redis
    SpringBoot非官方教程 | 第八篇:springboot整合mongodb
    SpringBoot非官方教程 | 第七篇:springboot开启声明式事务
    SpringBoot非官方教程 | 第六篇:springboot整合mybatis
    SpringBoot非官方教程 | 第五篇:springboot整合 beatlsql
    SpringBoot非官方教程 | 第四篇:SpringBoot 整合JPA
    SpringBoot非官方教程 | 第三篇:SpringBoot用JdbcTemplates访问Mysql
    SpringBoot非官方教程 | 第二篇:Spring Boot配置文件详解
    SpringBoot非官方教程 | 终章:文章汇总
    SpringBoot非官方教程 | 第一篇:构建第一个SpringBoot工程
  • 原文地址:https://www.cnblogs.com/liuqing576598117/p/10384142.html
Copyright © 2020-2023  润新知