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);
        }
    }
  • 相关阅读:
    数据绑定表达式语法(Eval,Bind区别)
    使用博客园的第一件事 自定义主题
    sql2000 跨服务器复制表数据
    使用UpdatePanel 局部刷新出现中文乱码的解决方法!!
    MMC不能打开文件MSC文件
    sql 日期 、时间相关
    loaded AS2 swf call function in AS3 holder
    Rewrite the master page form action attribute in asp.net 2.0
    100万个不重复的8位的随机数
    flash 中实现斜切变型
  • 原文地址:https://www.cnblogs.com/blazeZzz/p/9088857.html
Copyright © 2011-2022 走看看