首页 > 技术文章 > Java 反射

xfdhh 2019-07-28 19:52 原文

1、在程序运行过程中,可以对任意一个类型进行任意的操作。例如:加载任意类型、调用类型的任意方法、获取任意的成员变量、构造方法,可以创建该类型的对象。

2、如果要获取一个类型的各种内容,首先要获取这个类的字节码对象,解剖这个类型,获取类中的成员,需要使用Class类型中定义的方法。

3、反射就是这种动态的获取信息以及动态的访问成员的方式,称为反射。

4、获取类的字节码文件的三种方式

public class Test{

    public static void main(String[] args) throws Exception {
        Student stu = new Student();
        //第一种方法:通过对象名.getClass()
        Class class1 = stu.getClass();
        //第二种方法:类名.class
        Class class2 = Student.class;
        //第三种方法:Class.forName(全类名)
        Class class3 = Class.forName("com.test1.Student");
        System.out.println(class1==class2);
        System.out.println(class1==class3);
    }

}
class Student{
    private String name;
    int age;
    private void run() {
        System.out.println("run run run");
    }
    public void setName(String name) {
        this.name = name;
    }
    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public Student() {}
}
获取.class文件的三种方式

5、反射常用方法代码示例

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

public class Test1 {

    public static void main(String[] args) throws Exception {
        Student stu = new Student();
        Class class1 = stu.getClass();
        //获取到的.class文件.getField(属性名)获取属性 
        //getFields获取所有属性到一个数组中
        Field f1 = class1.getDeclaredField("age");
        //可以设置属性
        System.out.println(stu.age);
        f1.set(stu, 15);
        System.out.println(stu.age);
        //上面的方式无法得到私有属性,需要暴力反射
        Field f2 = class1.getDeclaredField("name");
        //暴力反射也分getDeclaredField()和getDeclaredFields(),原理同getFiled和getFileds
        //想要设置私有属性必须使用setAccessible()将里面的参数设为true
        f2.setAccessible(true);
        System.out.println(stu);
        f2.set(stu, "qq");
        System.out.println(stu);
        
        //获取构造方法getConstructor(构造方法里的参数类型.class) 返回一个Constructor构造器
        //这个构造器可以使用newInstance() 创建一个object类型的对象
        Constructor c = class1.getConstructor(String.class,int.class);
        Object obj = c.newInstance("bb",10);
        Student stu2 = (Student)obj;
        System.out.println(stu2);
        //同理,构造器也有getConstructors和暴力反射
        
        //获取成员方法getMethod(方法名, 参数.class)
        Method m1 = class1.getMethod("setName",String.class);
        //方法的使用,方法.invoke(对象名,参数)
        m1.invoke(stu2, "hh");
        System.out.println(stu2);
        //同理,有getMethods和暴力反射getDeclaredMethod...
        Method m2 = class1.getDeclaredMethod("run",null);
        //同理需要设置权限
        m2.setAccessible(true);
        m2.invoke(stu);
    }

}
class Student{
    private String name;
    int age;
    private void run() {
        System.out.println(name+"run run run");
    }
    public void setName(String name) {
        this.name = name;
    }
    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public Student() {}
    @Override
    public String toString() {
        return name+"..."+age;
    }
}

 

推荐阅读