zoukankan      html  css  js  c++  java
  • java基础之反射

    package zy.refactor;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    /*
     * 反射:主要作用于访问一个类的私有字段和私有方法
     * 使用流程1(已知类的字段以及方法):
     *         A:获取对象Class
     *         B:实例化对象
     *         C:根据字段名反射私有字段  class.getDeclaredField(字段名)
     *         D:打开允许访问的开关 setAccessible(true);
     *         E:赋值(set): name.set(dog, "二哈");  访问(get):    name.get(dog)
     *         F:根据方法名反射私有方法cls.getDeclaredMethod("eat", String.class, String.class);
     *         G:打开开关
     *         H:访问私有方法  m2.invoke(dog, "阿拉斯加", "全家桶");
     * 使用流程2(不知道类的字段及方法):
     *         A:获取对象Class
     *         B:根据Class反射所有的字段名称以及类型(循环Field[]得出字段名以及字段类型)
     *         C:根据Class反射构造方法
     *         D:根据构造方法创建对象(object类型)
     *         E:根据B中得到的字段名称和类型分别定义Field并打开开关然后给私有字段赋值 Field name = cls.getDeclaredField("name");
     *         F:访问私有字段
     *         G:反射私有方法(也可以反射Method[]数组 循环得出方法名等,类似反射字段数组)
     *         H:打开开关并访问私有方法
     */
    /**
     * 反射的应用
     * 
     * @author zy
     * @version 1.0
     */
    public class RefectorDemo {
        public static void main(String[] args) throws Exception {
            // 获取类的字节码对象(获取对象Class) 以下方法都可以
            // Class cls = dog.getClass();
            // Class cls = Dog.class;
            Class cls = Class.forName("zy.refactor.Dog");
            // -------------------------------------------------------方式1
            // 创建对象
            Dog dog = new Dog();
    
            // 反射私有字段
            Field name = cls.getDeclaredField("name");
            Field age = cls.getDeclaredField("age");
    
            // 打开开关
            name.setAccessible(true);
            age.setAccessible(true);
    
            // 赋值
            name.set(dog, "二哈");
            age.set(dog, 6);
    
            // 访问私有字段
            System.out.println(name.get(dog) + "--" + age.get(dog));
    
            // 反射私有方法
            Method m1 = cls.getDeclaredMethod("eat");
            Method m2 = cls.getDeclaredMethod("eat", String.class, String.class);
    
            // 打开开关
            m1.setAccessible(true);
            m2.setAccessible(true);
    
            // 访问私有方法
            m1.invoke(dog, null);
            m2.invoke(dog, "阿拉斯加", "全家桶");
    
            // -----------------------------------------------------------------下面是方式2
            System.out.println("----------------------------");
            // 反射所有的字段名称
            Field[] fields = cls.getDeclaredFields();
            // 此时已经知道一共有多少字段分别为什么 可以根据字段名称以及字段类型 进行赋值
            for (Field f : fields) {
                System.out.println(f.getType() + "--" + f.toString());
            }
            // 此时我们已经知道Dog类中有两个私有的字段,分别为String类型的name和int类型的age;下面我们就直接用了
    
            //反射所有方法 和反射字段基本类似
            Method[] methods = cls.getDeclaredMethods();
            for (Method m : methods) {
                System.out.println(m.getName());
            }
            
            
            // 反射构造方法
            Constructor con1 = cls.getConstructor();
            Constructor con2 = cls.getConstructor(String.class, int.class);
    
            // 根据反射的构造方法创建对象
            Object obj1 = con1.newInstance();// 创建对象
            Object obj2 = con2.newInstance("泰迪", 3);// 创建对象并赋值
    
            // obj1用的空构造方法
            // 给obj1对象的字段赋值(因为上面循环fields已经知道了这两个字段的name和type,这里就直接赋值了)
            name.set(obj1, "金毛");
            age.set(obj1, 4);
    
            // 访问私有字段
            System.out.println(name.get(obj1) + "--" + age.get(obj1));// 金毛--4
            System.out.println(name.get(obj2) + "--" + age.get(obj2));// 泰迪--3
            // 访问私有方法
            m1.invoke(obj1, null);
            m2.invoke(obj1, name.get(obj1), "金毛的食物");
            m1.invoke(obj2, null);
            m2.invoke(obj2, name.get(obj2), "泰迪的食物");
    
        }
    }
    
    
    package zy.refactor;
    
    /*
     * 反射用的dog类
     */
    public class Dog {
        private String name;
        private int age;
    
        public Dog() {
        }
    
        public Dog(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        private void eat() {
            System.out.println("狗吃骨头");
        }
    
        private void eat(String name, String food) {
            System.out.println(name + "吃" + food);
        }
    }
  • 相关阅读:
    Python实用笔记 (24)面向对象高级编程——使用@property
    Python实用笔记 (23)面向对象高级编程——使用__slots__
    Python实用笔记 (22)面向对象编程——实例属性和类属性
    Python实用笔记 (21)面向对象编程——获取对象信息
    Python实用笔记 (20)面向对象编程——继承和多态
    Python实用笔记 (19)面向对象编程——访问限制
    Python实用笔记 (18)面向对象编程——类和实例
    Python实用笔记 (17)模块
    Python实用笔记 (16)函数式编程——偏函数
    Python实用笔记 (15)函数式编程——装饰器
  • 原文地址:https://www.cnblogs.com/blazeZzz/p/9088857.html
Copyright © 2011-2022 走看看