java反射获取构造函数、成员变量、执行方法

java反射机制:

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

要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。

测试类:

package io.renren.modules.base;

import lombok.Data;

@Data
public class ReflectionDemo {

    public String name;

    private String address;
    private int age;

    public ReflectionDemo(){
        System.out.println("空参构造方法");
    }

    private ReflectionDemo(String name){
        this.name = name;
    }

    public ReflectionDemo(String name,int age, String address){
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public ReflectionDemo(String name,int age){
        this.age = age;
        this.name = name;
    }

//公有方法 public void eat(String food){ System.out.println("吃—"+food); }
//私有方法 private void save(Double money,Integer age){ System.out.println("【"+this.name+"】存了【"+money+"】钱"+",今年:"+age+"岁"); } }

开始测试:

package io.renren.modules.base;

import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;

/**
 * java类要经过编译—>运行两个阶段,编译器把.java文件编译成.class文件,
 * 而运行时期,则需要把class文件读进内存,过程分为:加载到内存、连接解析、初始化
 * 加载:把class文件读进内存,然后再创建一个class对象
 * 连接:协调类的内部, 将类的二进制数据中的符号引用替换为直接引用
 * 初始化
 * 1. 创建类的实例
 * 2. 类的静态变量,或者为静态变量赋值
 * 3. 类的静态方法
 * 4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
 * 5. 初始化某个类的子类
 */

//@SpringBootTest
public class reflectionTest {

    /**
     * 获取类的加载器
     */
    @Test
    public void test1(){
        Class c = ReflectionDemo.class;
        System.out.println(c);
        Class<? extends Class> aClass = c.getClass();
        System.out.println(aClass);
        ClassLoader classLoader = c.getClassLoader();
        URL resource = classLoader.getResource("");
        System.out.println(resource);

    }


    /**
     * 获取类的class对象,字节码对象
     */
    @Test
    public void test2(){
        //第一种方法
        ReflectionDemo demo = new ReflectionDemo();
        Class<? extends ReflectionDemo> aClass = demo.getClass();
        System.out.println(aClass);

        //第二种方法
        Class c = ReflectionDemo.class;
        System.out.println(c);

        //第三种方法
        try {
            Class cn = Class.forName("io.renren.modules.base.ReflectionDemo");
            System.out.println(cn);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

    /**
     * 获取构造方法、成员变量、成员方法
     */
    @Test
    public void test3() throws Exception{
        //获取空参构造方法
        Class c = ReflectionDemo.class;
        //获取所有public构造方法
        Constructor[] constructors = c.getConstructors();
        for (Constructor con: constructors){
            System.out.println(con);
        }

        //获取所有的构造方法,包括私有、公共
        Constructor[] constructors1 = c.getDeclaredConstructors();
        for (Constructor con: constructors1){
            System.out.println(con);
        }

        //获取某个公共的构造方法,参数类型要对应
        Constructor constructor = c.getConstructor(String.class, Integer.class);
        ReflectionDemo object =(ReflectionDemo) constructor.newInstance("小明", 190);
        System.out.println(object);


        Constructor constructor1 = c.getConstructor();
        System.out.println(constructor1);

        //获取某个构造方法,包括私有、公有
        Constructor declaredConstructors = c.getDeclaredConstructor(String.class);
        Constructor declaredConstructors2 = c.getDeclaredConstructor(String.class, Integer.class);
        System.out.println(declaredConstructors+"====="+declaredConstructors2);

        //private,取消 Java 语言访问检查
        declaredConstructors.setAccessible(true);
        ReflectionDemo object2 =(ReflectionDemo) declaredConstructors.newInstance("小明");
        System.out.println(object2);

        //获取所有公有变量
        Field[] fields = c.getFields();
        for(Field f: fields){
            System.out.println(f);
        }

        //获取所有变量
        Field[] declaredFields = c.getDeclaredFields();
        for(Field f: declaredFields){
            System.out.println(f);
        }

        //获取公有变量
        Field ageField = c.getField("name");
        System.out.println(ageField);

        //获取所有公有方法
        Method[] method = c.getMethods();
        for(Method m: method){
            System.out.println(m);
        }

        //获取公有方法
        Method method1 = c.getMethod("eat", String.class);
        System.out.println(method1);

        //获取方法、包括私有、公有
        Method method2 = c.getDeclaredMethod("save", Double.class);
        method2.setAccessible(true);
        System.out.println(method2);


    }


    /**
     * 获取成员变量
     */
    @Test
    public void test4() throws Exception{
        Class c = ReflectionDemo.class;
        //获取到有参构造方法
        Constructor con = c.getDeclaredConstructor(String.class);
        //赋值
        con.setAccessible(true);
        Object object = con.newInstance("小明");
        System.out.println(object);

        Field name = c.getField("name");
        Object value1 = name.get(object);

        Field name2 = c.getDeclaredField("age");
        name2.setAccessible(true);
        Object value2 = name2.get(object);

        //没赋值,为null
        Field name3 = c.getDeclaredField("address");
        name3.setAccessible(true);
        Object value3 = name3.get(object);

        System.out.println(value1);
        System.out.println(value2);
        System.out.println(value3);

    }

    /**
     * 执行方法
     */
    @Test
    public void test5() throws Exception{
        Class c = Class.forName("io.renren.modules.base.ReflectionDemo");

        Constructor constructor = c.getDeclaredConstructor(String.class);
        constructor.setAccessible(true);
        Object object = constructor.newInstance("小明");

        Method eatMethod = c.getMethod("eat", String.class);
        eatMethod.invoke(object, "菜果");

        Method saveMethod = c.getDeclaredMethod("save", Double.class,Integer.class);
        saveMethod.setAccessible(true);
        //反射执行方法,object,实例对象,也就是执行哪个实例的方法,方法的参数
        saveMethod.invoke(object,200000d,24);
    }



}