• Java中反射


    类加载的三种机制

    1、通过getClass

    People p =new People();
    Class c = p.getClass();
    

    2、People.class

    Class c1=People.class;
    

    3、Class.forName("tianpo.com.demo.People");

    Class c2=Class.forName("tianpo.com.demo.People");
    

    对象比较

    //比较内存地址,类加载器只会创建一次
    System.out.println(c==c2); 
    
    //比较的是属性值
    System.out.println(c.equals(c2));
    

    反射

    其实就是把class文件进行结构拆解:

    1. 构造函数(有参/无参)
    2. 成员变量(属性)
    3. 方法

    反射构造函数

    Class c =Class.forName("tianpo.com.demo.People");
    ## 有参
    Constructor constructor=c.getConstructor(String.class,int.class);
    ## 无参
    Constructor constructor1=c.getConstructor();
    
    Object obj=constructor.newInstance("dd",22);
    People p =(People)obj;
    System.out.println(p);
    

    暴力反射(不建议使用,破坏了封装性、安全性)

    如果方法是 private修饰的,当你用反射去访问的时候
    setAccessible(true); 之后才能访问;另外从某方面说,选择它可以提高反射的速度,因为不需要再通过语言检查了。

    //构造函数是私有的 private People(String name, int age) { super(); this.name = name; this.age = age; } Class c =Class.forName("tianpo.com.demo.People"); Constructor constructor=c.getDeclaredConstructor(String.class,int.class); //暴力反射,取消运行时权限检查 constructor.setAccessible(true); Object obj=constructor.newInstance("dd",22); System.out.println(obj);


    动态调用内部方法

    Class c = Class.forName("tianpo.com.demo.People");
    Constructor con = c.getConstructor();
    Method m =c.getMethod("eat");
    Object obj1=con.newInstance();
    m.invoke(obj1);
    

    获取所有成员变量

    Class c = Class.forName("tianpo.com.demo.People");
    # 获取所有public类型的成员变量
    Field[] fs=c.getFields();
    # 获取所有private
    Field[] fs1=c.getDeclaredFields();
    
    for(Field field:fs){
        System.out.println(field);
    }
    
    Field field=c.getDeclaredField("age");
    Constructor con = c.getConstructor();
    Method m =c.getMethod("eat");
    Object obj1=con.newInstance();
    //动态赋值
    field.set(obj1,18);
    System.out.println(obj1);
    

    反射的泛型擦除

    ArrayList<String> array = new ArrayList<String>();
    array.add("张三");
    // 编译时会做类型检查
    //array.add(10);
    Class c = array.getClass();
    Method m = c.getMethod("add",Object.class);
    m.invoke(array,10);
    m.invoke(array,13.8);
    System.out.println(array);
    

    通过配置执行调用

    创建一个config.properties

    className = tianpo.com.demo.People
    methodName = eat
    
    className = tianpo.com.demo.Student
    methodName = Study
    
    className = tianpo.com.demo.Worker
    methodName = Work
    

    反射调用

    FileReader rd = new FileReader("config.properties");
    Properties pro = new Properties();
    pro.load(rd);
    rd.close();
    String className = pro.getProperty("className");
    String methodName = pro.getProperty("methodName");
    Class c =Class.forName(className);
    Method m = c.getMethod(methodName);
    Object obj=c.newInstance();
    m.invoke(obj);
  • 相关阅读:
    软件 = 程序 + 软件工程(构建之法读书笔记一)
    网站系统开发需要掌握的技术
    C++迪杰斯特拉算法求最短路径
    strcpy函数在VS2015无法使用的问题
    C++哈夫曼树编码和译码的实现
    java学习中一些疑惑解答(2)
    凯撒加密、解密算法
    利用DOS批处理实现定时关机操作
    C及C++中typedef的简单使用指南
    java学习中的一些疑惑解答
  • 原文地址:https://www.cnblogs.com/tianboblog/p/9218289.html
Copyright © 2020-2023  润新知