zoukankan      html  css  js  c++  java
  • 关于JAVA中的反射机制的总结


    在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法,并能够实例化该类成对象,并调用其方法和成员。这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

    JAVA中的反射机制是一种能够大大增强程序扩展性的技术。当一个程序封装完成后(生成exe文件),如果想要对该程序进行功能扩展,不用进行代码的重新修改(也不可能拿到源码),只要修改配置文件(一般是XML)就可以完成扩展。

    这样的程序为外部提供了一个接口,只要按照该接口的规则定义一个对象(功能),即可以为应用程序扩展该功能。

    可以这样比喻,你买了一块电脑主板(封装好的程序),此时你想要添加一块声卡(要扩展的功能),此时只能够通过一个pci接口(应用程序提供的接口)来进行扩展。声卡的接口必须符合PCI的规则才可以被主板使用。通过添加驱动程序(修改XML配置文件)来进行扩展功能。

    具体到代码实现分为以下几步:

    1、定义一个接口(PCI)及一系列的方法用作加载功能。

    2、定义一个对象并且实现该接口,复写其中的方法。

    3、在配置文件中添加该对象的名称(全名,包括路径)键值对。

    4、定义一个输入流,读入配置文件进properties集(健壮性判断);

    5、使用for循环挨个获取properties集中的对象名称;

    6、获取名称后用Class加载这个类,并实例化一个该对象(可以直接进行类型强转,因为已知是PCI接口)。

    7、使用对象。

    1         File configFile = new File("pci.properties");
     2         
     3         Properties prop = new Properties();
     4         FileInputStream fis = new FileInputStream(configFile);
     5         
     6         prop.load(fis);
     7         
     8         for(int x=0; x<prop.size(); x++){
     9             
    10             String pciName = prop.getProperty("pci"+(x+1));
    11             
    12             Class clazz = Class.forName(pciName);//用Class去加载这个pci子类。 
    13             
    14             PCI p = (PCI)clazz.newInstance(); //PCI接口已经定义好了,有open和close两个方法
    15             
    16             mb.usePCI(p);//mb是主板对象,定义了一个使用PCI接口对方法
    17         }
    18         
    19         fis.close();

     不仅如此,有时还需要或得该对象的有参数构造器,成员,成员方法

    1、创建对象实例

    //1、指定该类的名称
    String className = "cn.itcast.bean.Person";
    //2、通过Class类的forName()方法获取该类(从.class文件中获取)
    Class clazz = Class.forName(className);
    //3、通过Class对象的newInstance()方法创建对象,无参构造器
    Object obj = clazz.newInstance();

    问题:

    1、从上面代码可以发现,如果要用有参构造器实例化对象的话就不行

    2、实例化的对象时Object类,要想办法downcast

    2、获取其任意构造器

    String name = "cn.itcast.bean.Person";
    //1、找寻该名称类文件,并加载进内存,并产生Class对象。
    Class clazz = Class.forName(name);
    //2、获取到了指定的构造函数对象,构造器也有自己的对象。getConstructor(,)的参数列表对应于所需构造器的参数列表的类对象
    Constructor constructor = clazz.getConstructor(String.class,int.class);
            
    //3、通过该构造器对象的newInstance方法进行对象的初始化。
    Object obj = constructor.newInstance("小明",38);

    3、获取其成员

    Class clazz = Class.forName("cn.itcast.bean.Person");
    
    Field field = null;
    
    //clazz.getField("age");//只能获取公有的,
    
    field = clazz.getDeclaredField("age");//只获取本类,但包含私有。 参数为成员名
    
    //对私有字段的访问取消权限检查。暴力访问。
    field.setAccessible(true);
    
    Object obj = clazz.newInstance();
    
    field.set(obj, 89);//将obj对象中的对应field成员值设为89
    
    
    Object o = field.get(obj);//返回obj对象中的field成员的值
    
    System.out.println(o);//89

    4、获取方法(类似于构造器的获取)

    public static void getMethodDemo_3() throws Exception {
            
        Class clazz = Class.forName("cn.itcast.bean.Person");
            
        Method method = clazz.getMethod("paramMethod", String.class,int.class);//第一个参数是方法名,考虑到重载,所以后面要加上参数列表来定位唯一的方法
            
        Object obj = clazz.newInstance();
            
        method.invoke(obj, "小强",89);//调用obj对象中的method方法,且传递了参数。
                
    }
    public static void getMethodDemo() throws Exception {
            
        Class clazz = Class.forName("cn.itcast.bean.Person");
            
        Method[] methods  = clazz.getMethods();//获取的都是公有的方法。 
        methods = clazz.getDeclaredMethods();//只获取本类中所有方法,包含私有。 返回一个方法数组,方法对象数组
        for(Method method : methods){
            System.out.println(method);
        }        
    }
  • 相关阅读:
    2.列出目录内容
    mongo2csv
    Python-uiautomator使用说明文档
    uiautomator设备和选择器~Python详解
    hadoop1.2开发环境搭建
    postgresql 查询某一个表中的所有字段
    VolgaCTF 2020 Qualifier Library
    VolgaCTF 2020 Qualifier Newsletter
    2019-2020-2 网络对抗技术 20175211 Exp3 免杀原理与实践
    BJDCTF 2nd Writeup
  • 原文地址:https://www.cnblogs.com/njupt-Qsimple/p/5351626.html
Copyright © 2011-2022 走看看