反射

  了解反射先要了解字节码文件对象

Class类

  字节码文件对象 就是 Class 类的对象

       这个 Class 和 定义一个类的 class 关键字是不一样的, class 是用来定义一个类, Class 是 Java 中的一个类型;

字节码文件

  java 源文件 进行编译(javac)之后的 .class文件。

字节码文件对象  

  jvm 将字节码文件加载到 jvm 内存中, jvm就 认为这个字节码文件是一个字节码文件对象;

如何获取字节码文件对象

  1、Object 类的 getClass 方法;

Person p = new Person();
 Class class1 = p.getClass();

  2、类型  .class 属性

Class class2 = Person.class;

  3、Class.forName("类的路径")

Class class3 = Class.forName("com.jm.pojo.Person");

使用字节码文件对象

1、字节码文件包含

     类                     字节码文件对象

  构造方法      构造方法对象 (类型 Constructor )

  成员变量      成员变量对象 (类型 Field )

  成员方法      成员方法对象 (类型 Method )

2、用字节码文件对象构建一个类的对象

2.1、用 new 创建对象

      之前用 new 的 方式创建一个类的对象

Person p = new Person();

      Person() 是类的构造方法,因为对象是通过构造方法创建; 

2.2、用字节码文件中的构造器对象来创建一个类的对象 ---- Constructor对象

Person

public class Person implements Serializable {

    public Person(){};

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    private String name;

    private Integer age;

    public void eat(){
      System.out.println("吃饭。。。");
    }


}

测试

public static void main(String[] args) throws Exception{

        Person p = new Person();
        // 用字节码文件对象创建一个类的对象
        Class clazz = Class.forName("com.jm.pojo.Person");
        // 得到字节码文件中的构造器对象
        Constructor[] constructors = clazz.getConstructors();

        System.out.println(constructors.length);
        System.out.println(constructors[0]);
        System.out.println(constructors[1]);

        Constructor c = constructors[0];
        // 用构造器对象常见类的对象
        Object obj = c.newInstance();
        Person p2 = (Person) obj;
        p2.eat();
    }

打印

2
public com.jm.pojo.Person()
public com.jm.pojo.Person(java.lang.String,java.lang.Integer)
吃饭。。。

3、构造方法对象( Constuctor )

3.1、方法对象( Method )

       getMethods() : 获取到包括父类继承过来的方法

       getDeclaredMethods() : 获取类当前的所有方法 

        Person p = new Person();
        // 用字节码文件对象创建一个类的对象
        Class clazz = Class.forName("com.jm.pojo.Person");
        // 得到字节码文件中的构造器对象
        Method[] methods = clazz.getDeclaredMethods();
        for(Method method: methods){
            System.out.println(method);
        }

打印

public java.lang.String com.jm.pojo.Person.getName()
public void com.jm.pojo.Person.setName(java.lang.String)
public java.lang.Integer com.jm.pojo.Person.getAge()
public void com.jm.pojo.Person.eat()
public void com.jm.pojo.Person.setAge(java.lang.Integer)

3.2、获取特定方法

        getMethod("the name of the method")

        

3.2.1 执行特定方法 invoke

      传统调用方法  : 对象 。方法 ( 实参 )

      反射调用方法  : 方法 。invoke (对象, 实参)

      如果方法是private 则 先获取 getDeclaredMethod 再 setAccessble(true)

给 Person 类加个方法

    public String method(String param){
        System.out.println("get method "+ param);
        return param;
    }

测试调用特定方法

    public static void main(String[] args) throws Exception{

        Person p = new Person();
        // 用字节码文件对象创建一个类的对象
        Class clazz = Class.forName("com.jm.pojo.Person");
        // 得到字节码文件中的构造器对象
        Method method = clazz.getMethod("method", String.class);
        System.out.println(method);

        // 字节码文件对象提供一个边界创建类对象的方法
        Object newInstance = clazz.newInstance();
        // 反射调用
        Object rst = method.invoke(newInstance, "test");
        System.out.println(rst);
    }

打印

public java.lang.String com.jm.pojo.Person.method(java.lang.String)
get method test
test

4、成员变量

     getFileld

原文地址:https://www.cnblogs.com/Jomini/p/13657565.html