美文网首页
2018-05-19java反射

2018-05-19java反射

作者: WaterRice | 来源:发表于2018-05-19 23:28 被阅读0次
                                 java 基础------反射机制
    

    一.反射的概述

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。


    二.反射的工作原理

    要想通过反射解剖一个类(比如创建该类的对象,访问该类的属性,调用该类的方法等等),可拆分为以下步骤操作:

    • 得到该类对应的字节码对象,即类名.class对象
    • 通过该类的字节码对象,调用相应的方法完成相应的目的
    package reflect;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    public class Demo1 {
    
        /**
         * @throws Exception 
         * 
         */
        public static void main(String[] args) throws Exception {
        
            //通过文件路径得到字节码对象
            Class<?> clazz = Class.forName("reflect.Student");
            //字节码对象调用该方法产生类的对象实例
            Student student = (Student)clazz.newInstance();
            System.out.println(student);
            
            /*-------------------------------------------------------------*/
            //通过字节码对象得到该类的setId()方法
            Method setIdMethod = clazz.getDeclaredMethod("setId", Integer.class);
            //通过字节码对象得到该类的setName()方法
            Method setNameMethod = clazz.getMethod("setName", String.class);
            //执行得到的方法
            setIdMethod.invoke(student, 20);
            setNameMethod.invoke(student, "张三");
            
            System.out.println(student);
            /*-------------------------------------------------------------*/
            //通过字节码对象得到该类的所有属性
            Field[] field = clazz.getDeclaredFields();
            for (Field field2 : field) {
                System.out.println(field2);
            }
        }
    
    }
    
    class Student{
        private int id;
        private String name;
        
        public Student() {
            super();
            // TODO Auto-generated constructor stub
        }
        public Student(int id,String name){
            this.id = id;
            this.name = name;
        }
        public int getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public String toString(){
            return "["+this.id+","+this.name+"]";
        }
        
    }
    

    ps:里面两组方法注意一下

    • getDeclaredFields():可以是类的任何属性
    • getFields():只能是公开属性
      getDeclaredMethod()和getMethod()分别与此类似。

    下面利用反射搞点事情。。。

    在List<Integer>插入一个字符串值

    package reflect;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    import java.util.List;
    
    public class Demo1 {
    
        /**
         * @throws Exception 
         * 
         */
        public static void main(String[] args) throws Exception {
        
            List<Integer> list = new ArrayList<>();
            list.add(1);
            list.add(2);
            list.add(30);
            //得到List.class对象
            Class<?> clazz = Class.forName("java.util.List");
            //得到add方法
            Method method = clazz.getMethod("add",Object.class);
            //执行add该方法
            method.invoke(list, "hahaha");
            
            System.out.println(list);
        }
    }
    
    image.png

    原理分析:

    • List<Integer>被编译后泛型会被替换,从实验中来看,应该是替换成了List<Object>;
    • 而通过反射机制得到被编译后的add()方法,此时该方法的参数类型已经是Object了,然后就可以为所欲为了。。。

    相关文章

      网友评论

          本文标题:2018-05-19java反射

          本文链接:https://www.haomeiwen.com/subject/gggadftx.html