2018-05-19java反射

                             java 基础------反射机制

一.反射的概述

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。


二.反射的工作原理

要想通过反射解剖一个类(比如创建该类的对象,访问该类的属性,调用该类的方法等等),可拆分为以下步骤操作:

  • 得到该类对应的字节码对象,即类名.class对象
  • 通过该类的字节码对象,调用相应的方法完成相应的目的
package reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Demo1 {

    /**
     * @throws Exception 
     * 
     */
    public static void main(String[] args) throws Exception {
    
        //通过文件路径得到字节码对象
        Class clazz = Class.forName("reflect.Student");
        //字节码对象调用该方法产生类的对象实例
        Student student = (Student)clazz.newInstance();
        System.out.println(student);
        
        /*-------------------------------------------------------------*/
        //通过字节码对象得到该类的setId()方法
        Method setIdMethod = clazz.getDeclaredMethod("setId", Integer.class);
        //通过字节码对象得到该类的setName()方法
        Method setNameMethod = clazz.getMethod("setName", String.class);
        //执行得到的方法
        setIdMethod.invoke(student, 20);
        setNameMethod.invoke(student, "张三");
        
        System.out.println(student);
        /*-------------------------------------------------------------*/
        //通过字节码对象得到该类的所有属性
        Field[] field = clazz.getDeclaredFields();
        for (Field field2 : field) {
            System.out.println(field2);
        }
    }

}

class Student{
    private int id;
    private String name;
    
    public Student() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Student(int id,String name){
        this.id = id;
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString(){
        return "["+this.id+","+this.name+"]";
    }
    
}

ps:里面两组方法注意一下

  • getDeclaredFields():可以是类的任何属性
  • getFields():只能是公开属性
    getDeclaredMethod()和getMethod()分别与此类似。

下面利用反射搞点事情。。。

在List插入一个字符串值

package reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class Demo1 {

    /**
     * @throws Exception 
     * 
     */
    public static void main(String[] args) throws Exception {
    
        List list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(30);
        //得到List.class对象
        Class clazz = Class.forName("java.util.List");
        //得到add方法
        Method method = clazz.getMethod("add",Object.class);
        //执行add该方法
        method.invoke(list, "hahaha");
        
        System.out.println(list);
    }
}
image.png

原理分析:

  • List被编译后泛型会被替换,从实验中来看,应该是替换成了List
  • 而通过反射机制得到被编译后的add()方法,此时该方法的参数类型已经是Object了,然后就可以为所欲为了。。。
  • 你可能感兴趣的:(2018-05-19java反射)