反射

反射

概念:java反射机制是在运行时,对于任意一个类,都能够知道这个类的所有属性和方法;
        对于任意一个对象,都能够调用它的方法和属性。
类加载器:
    1.Bootstrap ClassLoader :根类加载器
    2.Extension ClassLoader :扩展类加载器
    3.System ClassLoader :系统类加载器(自己定义的类)
步骤:
    一.要想使用反射,首先要获取该类对应的字节码文件对象
        获取class文件对象的三种方式
            1.通过Object类中的getClass()方法;
            2.通过静态属性class. 例:Class c = Student.class;
            3.[常用]通过Class类中的静态方法forName();
                Class.forName(className:该类的全类名(带包的类))
    二.剖析一个类
        一个类的构成:构造方法(Constructor).成员变量(Field).成员方法(Method).
        1.Constructor
            (1)获取字节码文件对象
            (2)获取构造方法对象
                 A:获取所有构造方法
                 public Constructor[] getConstructors() 获取所有的构造方法对象数组 不包含私有的
                 public Constructor[] getDeclaredConstructors() 获取所有的构造方法对象,包括私有的
                 B:获取单个构造方法
                 public Constructor getConstructor(Class... parameterTypes)获取指定的公有的构造方法
                 public ConstructorgetDeclaredConstructor(Class...parameterTypes:可变参数:数据类型.class)获取指定的公有私有的构造方法

                 取消语法检查:setAccessible(true)

            (3)创建该类的对象
                newInstance(Objecct...initarges)
        2.Field
            (1)获取字节码文件对象
            (2)获取字段对象
                 A:获取所有成员变量
                 public Field[] getFields() 获取所有的字段 不包含私有字段  (包括父类公有)
                 public Field[] getDeclaredFields() 获取所有字段 包含私有字段 (无父类)
                 B:获取单个成员变量
                 public Field getField(String name) 获取单个的公有字段
                 public Field getDeclaredField(String name) 获取单个的公有字段或私有字段
            (3)给字段赋值
                set(Object obj , Object value)
                        对象      值

        3.Method
            (1)获取字节码文件对象
            (2)获取成员方法对象
                 A:获取所有成员方法
                 public Method[] getMethods() 获取所有的共有的方法对象 包括父类的公共方法
                 public Method[] getDeclaredMethods() 获取所有的方法对象 包括私有的
                 B:获取单个成员方法
                 public Method getMethod(String name,Class...parameterTypes) 获取指定的方法对象
                 public Method getDeclaredMethod(String name,Class...parameterTypes) 获取私有的方法对象

            (3)执行方法
                invoke(Object obj , Object ... args);
                        对象      方法所要的实参

    需求:通过反射的方法用文件实现方法的调用

    代码:
        public class Student {
            public void show(){
                System.out.println("这是学生类中的SHOW方法!");
            }
            public void method(){
                System.out.println("这是学生类中的METHOD方法!");
            }
        }

        public class Teacher {
            public void show(){
                System.out.println("这是老师类中的SHOW方法!");
            }
            public void method(){
                System.out.println("这是老师类中的METHOD方法!");
            }
        }

        public static void main(String[] args) throws IOException, Exception {
            Properties p = new Properties();
            p.load(new FileInputStream("a.txt"));

            String name = p.getProperty("name");
            String method = p.getProperty("method");

            //获该类的字节码文件对象
            Class cla=Class.forName(name);
            //获取该成员方法,使用保险的方法
            Method m = cla.getDeclaredMethod(method);

            //执行该方法
            m.invoke(cla.newInstance());
        }

        文件:
        name=reflect.demo.Teacher
        method=method

        结果:
        这是老师类中的METHOD方法!

    需求:通过反射写一个通用的设置某个对象的某个属性为指定的值

    代码:
        public class Student {
            private String name;
            private int age;

            @Override
            public String toString() {
                return "Student [name=" + name + ", age=" + age + "]";
            }
        }


        public class MyTools {
            public static void set(Student s, String string, String string2) throws Exception {
                // 获取字节码文件对象
                Class c = s.getClass();

                Field f = c.getDeclaredField(string);
                f.setAccessible(true);
                f.set(s, string2);
            }
        }


        public static void main(String[] args) throws Exception {
            Student s = new Student();

            MyTools.set(s,"name","张三");

            System.out.println(s);
        }

        结果:         
        Student [name=张三, age=0]

你可能感兴趣的:(反射)