java反射

1、反射概述

  • JAVA反射机制是在运行状态中,对于任意一个类都能够知道这个类的所有属性和方法;
  • 对于任意一个对象,都能通过反射够调用它的任意一个方法和属性
  • 要想解剖一个类,必须先要获取到该类的字节码文件对象。

 

2、获取字节码对象三种方式

  • Object类的getClass()方法,判断两个对象是否是同一个字节码文件
  • 静态属性class,锁对象
  • Class类中静态方法forName()
public static void main(String[] args) throws ClassNotFoundException {
        //1.Object类的getClass()方法
        Person p = new Person();
        Class clz1 = p.getClass();
        
        //2.静态属性clas
        Class clz2 = Person.class;
        
        //3.Class类中静态方法forName()
        /**
         * 参数 forName(String className) 传类全路路(包名+类名)
         */
        Class clz3 = Class.forName("lesson05.Person");
        
        //4.字节码对象在内存中只有一个
        System.out.println("clz1:" + clz1.hashCode());
        System.out.println("clz2:" + clz2.hashCode());
        System.out.println("clz3:" + clz3.hashCode());
    }

3、案例读取配置文件创建字节码对象

//1.读取info.txt文件内容
        FileReader fr = new FileReader("info.txt");
        BufferedReader br = new BufferedReader(fr);
        String className = br.readLine();
        br.close();
        
        //2.获取字节码对象
        Class clz = Class.forName(className);
        System.out.println(clz);



info.txt
lesson6.Person

4、通过反射获取参构造方法

使用要点:

 1.如果要使用反射,先要获取字节码对象

 2.通过字节码对象的getConstructor()可以获取到构造方法对象

 3.构造方法对象(Contructor),有个newInstance方法创建这个字节码对象

 4.反射是在java.lang.reflect这个包中

 5.反射的作用一般是用于写框架(ssh,ssm)

 

代码:

 //1.获取字节码对象
        Class clz = Teacher.class;
        
        //2.获取构造方法
        //2.1 无参构造方法
        Constructor c1 = clz.getConstructor();
    
        //2.2 通过构造方法创建对象
        Teacher teacher1 = (Teacher) c1.newInstance();
        System.out.println("teacher1:" + teacher1);
        
        //2.3 获取有参构造方法
        /**
         * parameterType 参数类型
         */
        Constructor c2 = clz.getConstructor(String.class,String.class);
        Teacher teacher2 = (Teacher) c2.newInstance("gyf","梅州");//相当于调用new Teacher("gyf","梅州")
        System.out.println("teacher2:" + teacher2);
        
        Constructor c3 = clz.getConstructor(String.class,double.class);
        Teacher teacher3 = (Teacher) c3.newInstance("gyf",1.70);//相当于调用new Teacher("gyf","梅州")
        System.out.println("teacher3:" + teacher3);

5、通过反射获取类属性

使用要点

1.Class的getField(String)方法可以获取类中的指定字段(可见的),

2.如果是私有的,可以用getDeclaedField("name")方法获取

3.通过set(obj, "李四")方法可以设置指定对象上该字段的值

4.如果是私有的需要先调用setAccessible(true)设置访问权限,

5.调用get(obj)可以获取指定对象中该字段的值

代码

//1.获取字节码对象
        Class clz = Teacher.class;
        
        //2.获取color字段
        Field colorField = clz.getField("color");
        System.out.println(colorField);
        
        //3.通过反射给字段赋值
        Teacher teacher = new Teacher();
        //teacher.color = "白色";
        colorField.set(teacher, "黄色");
        
        //4.获取私有name属性
        Field nameField = clz.getDeclaredField("name");    
        System.out.println(nameField);
        
        //5.通过反射给私有属性赋值
        nameField.setAccessible(true);//设置私有属性可以访问
        nameField.set(teacher, "gyf");
        
        System.out.println(teacher);
        
        //6.通过反射获取私有属性的值
        Object value = nameField.get(teacher);
        System.out.println(value);

6、通过反射获取方法并使用

使用要点

1.反射中通过Method类描述方法【构造方法:Contructor,字段:Field】

2.通过Class的getMethod可以获取一个方法

3.通过getDeclaredMethod可以获取私有方法

4.如果要调用私有方法,设置访问权限setAccessible

代码

 //1.获取字节码对象
        Class clz = Teacher.class;
                
        Teacher teacher = new Teacher();
    /*    teacher.say1();
        teacher.say2("小黄鸭");
        teacher.say3("小黄鸭",2);*/
        
        //2.通过反射调用方法
        //2.1 获取无参方法
        Method m1 = clz.getDeclaredMethod("say1");
        //2.1 获取有参方法
        Method m2 = clz.getDeclaredMethod("say2", String.class);
        Method m3 = clz.getDeclaredMethod("say3", String.class,int.class);
    
        //设置私有方法可以访问
        m1.setAccessible(true);
        m2.setAccessible(true);
        m3.setAccessible(true);
        //3.2 调用方法
        m1.invoke(teacher);
        m2.invoke(teacher, "小猪");
        m3.invoke(teacher, "小狗",98);

7、案例越过泛型的检查

//1.声明泛型集合
        List<Integer> list = new ArrayList<Integer>();
        
        list.add(110);
        list.add(120);
        list.add(130);
        //list.add("gyf");
        
        //2.通过反射往集合添加字符串
        //2.1 获取字节码对象(Class)
        Class clz = list.getClass();
        
        //2.2 通过反射获取方法
        Method method = clz.getMethod("add", Object.class);
        
        //2.3 调用方法
        method.invoke(list, "gyf");
        
        System.out.println(list);

8、写一个通用的方法,设置对象的属性值

 

posted @ 2018-12-22 22:30  expworld  阅读(98)  评论(0编辑  收藏  举报