美文网首页
反射入门

反射入门

作者: ONE_PIECES | 来源:发表于2019-04-23 16:29 被阅读0次
    • Java的反射机制实在运行状态中,对于一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的方法和属性,这种动态获取的获取信息以及动态调用对象的方法的功能称为java语言的反射
    • 想要解剖一个类,必须先要获取该类的字节码文件对象(类的信息都存储在这里面了呢),解剖使用的就是Class类对象
    1.1 获取Class类型的对象
      // 方式一: 获取一个类字节码文件对象
            Person person = new Person("henson");
            Class aClass = person.getClass();
            // System.out.println(aClass);
    
            // 方式二:
            Class bClass = Person.class;
    
            // 方式三:
            // java.lang.ClassNotFoundException: Person
            Class cClass = Class.forName("com.cskaoyan.reflection.Person");      
    
    1.2 通过反射获取类构造方法&&创建对象
       // 1. 获取类的字节码文件对象
            Class aClass = Class.forName("com.cskaoyan.reflection.Person");
            //获取public类型的
            Constructor[] constructors = aClass.getConstructors();
             //获取所有类型的
            Constructor[] declaredConstructors = aClass.getDeclaredConstructors();
            for (Constructor c : declaredConstructors) {
                System.out.println(c);
            }
            
            // 如何通过 Construtor 对象生成对象
            // T newInstance(Object... initargs)  Object[] 参数个数可以是任意个(包括0个)
            // Uses the constructor represented by this Constructor object to create and initialize
            // a new instance of the constructor's declaring class, with the specified initialization parameters.
    
            // 获取无参构造方法
            Constructor constructor = aClass.getConstructor();
            Object o = constructor.newInstance();
            System.out.println(o);
    
            // 获取两个参数的构造方法(public)
            // Constructor<T>   getConstructor(Class<?>... parameterTypes)
    
            //获取私有的方法;需要设置Access
            Constructor constructor1 = aClass.getDeclaredConstructor(String.class, int.class);
            // void setAccessible(boolean flag)
            //Set the accessible flag for this object to the indicated boolean value.
            constructor1.setAccessible(true);
            // 自动装箱 拆箱  把基本数据自动装箱成相应的引用数据类型 Integer
            Object allen = constructor1.newInstance("Allen", 18);
            System.out.println(allen);
        }
    

    通过反射获取成员变量并使用

         // 1. 获取字节码文件对象
            Class aClass = Class.forName("com.cskaoyan.reflection.Person");
            // 2. 通过字节码文件对象获取属性(域)
            // 获取父类和自己公共的成员属性和静态属性(public)
               Field[] fields = aClass.getFields();
            // 获取自己定义的所有的成员属性和静态属性(包括private)
            Field[] declaredFields = aClass.getDeclaredFields();
    
            /*
                Person person = new Person();
                person.name = "Trista"; //public
                person.age = 18;       //private
             */
    
            Object o = aClass.newInstance();
            System.out.println(o);
            Field nameField = aClass.getField("name");
            // 第一参数:表示要对哪个对象进行赋值
            // 第二参数:该对象的该属性要新赋予的值
            nameField.set(o, "Trista");
            System.out.println(o);
    
            // NoSuchFieldException: age,private类型
            Field age = aClass.getDeclaredField("age");
            age.setAccessible(true);
            age.set(o, 18);
            System.out.println(o);
        }
    
    获取成员方法
           //1 .获取字节码文件对象
            Class aClass = Class.forName("com.cskaoyan.reflection.Person");
    
            // 获取父类和子类中公共的成员方法和静态方法
             Method[] methods = aClass.getMethods();
            // 获取该类中声明的所有成员方法和静态方法
            Method[] declaredMethods = aClass.getDeclaredMethods();
    
    
          Constructor declaredConstructor = aClass.getDeclaredConstructor(String.class, int.class);
            declaredConstructor.setAccessible(true);
            Object jenny = declaredConstructor.newInstance("Jenny", 18);
            // Object   invoke(Object obj, Object... args)
            // 获取某个方法
            Method getAge = aClass.getMethod("getAge");
            //相当于对象.方法,(有参数,再后面加上)
            Object invoke = getAge.invoke(jenny); // 自动拆箱
            System.out.println(invoke);
    
            //如果是private方法,设置Access
            Method show = aClass.getDeclaredMethod("show");
            show.setAccessible(true);
            Object result = show.invoke(jenny);
            System.out.println(result);
    
        }
    

    注:
    通过反射访问类

       private Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public Person() {
        }
    
        Person(String name) {
            this.name = name;
        }
    
        private static void show() {
            System.out.println("show self");
        }
    
        public int getAge() {
            return age;
        }
    

    相关文章

      网友评论

          本文标题:反射入门

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