Java反射

概念

Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。

class类

Class类是一个比较特殊的类,它是反射机制的基础,Class类的对象表示正在运行的Java程序中的类或接口,也就是任何一个类被加载时,即将类的.class文件(字节码文件)读入内存的同时,都自动为之创建一个java.lang.Class对象。Class类没有公共构造方法,其对象是JVM在加载类时通过调用类加载器中的defineClass()方法创建的,因此不能显式地创建一个Class对象。通过这个Class对象,才可以获得该对象的其他信息。下表列出了Class类的一些常用方法。
要使用反射,要先获取class类

建立一个Person类作为实验对象

public class Person {
    private String name;
    private String address;
    public int age;

    public Person() {
    }

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

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

    public String getName() {
        return name;
    }

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

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public void show(){
        System.out.println("Person中show方法被调用");
    }


}

获取class对象

	//反射获取class对象 首先要先获取.class文件,字节码文件
    public static void getClass1(){

        try {
            //在代码编写阶段获取
            Class class1 = Class.forName("com.hu.reflect.Person");
            System.out.println("代码编写阶段:"+class1);
            System.out.println("=======================================");
            //在字节码阶段获取
            Class<Person> personClass = Person.class;
            System.out.println("在字节码阶段:"+personClass);
            System.out.println("=======================================");
            //在虚拟机运行阶段获取
            Person p = new Person();
            Class pClass = p.getClass();
            System.out.println("在虚拟机运行阶段:"+pClass);
            System.out.println("=======================================");

            System.out.println(class1==personClass);
            System.out.println(class1==pClass);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

获取构造方法并实例化对象

	//反射获取构造方法并实例化对象
    public static void getConstructor1(){
        Class<Person> personClass = Person.class;
        //获得全部构造方法
        Constructor<?>[] constructors = personClass.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }
        System.out.println("=======================================");
        //获取指定的构造方法
        try {
            Constructor<Person> constructor1 = personClass.getConstructor();//通过指定的参数来确定构造方法,此处为无参
            System.out.println(constructor1);
            Person person = constructor1.newInstance();//相当于Person p = new Person()
            person.show();//方法能被调用,说明实例化成功

            System.out.println("=======================================");
            Constructor<Person> constructor = personClass.getConstructor(String.class);//通过指定的参数来确定构造方法
            System.out.println(constructor);
            Person huge = constructor.newInstance("huge");//相当于Person p = new Person("huge")
            //这个地方相当于调用了构造方法
            System.out.println(huge.getName());
            System.out.println(huge.getAddress());
            huge.show();//方法能被调用,说明实例化成功
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

获取普通方法并操作

	//反射获取普通方法并操作
    public static void getMethod1(){
        Person person = new Person();
        Class personClass = person.getClass();
        //getMethods()获取的是本类及其父类所有的公共方法
        Method[] method = personClass.getMethods();
        for (Method method1 : method) {
            System.out.println(method1);
        }

        System.out.println("=======================================");
        //getDeclaredMethods()获取的是本类所有的公共方法
        Method[] declaredMethods = personClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }

        System.out.println("=======================================");
        //调用具体的方法并执行
        try {
            //获取无参的普通方法,反射中调用invoke()执行方法
            Method m1 = personClass.getDeclaredMethod("show");
            m1.invoke(person);

            //获取有参的方法执行
            Method m2 = personClass.getDeclaredMethod("setName", String.class);
            m2.invoke(person,"huge");
            //查看是否执行成功
            System.out.println(person.getName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

获取成员变量并操作

    //反射获取成员变量并操作
    public static void getFiled1() {

        try {
            Class pClass = Class.forName("com.hu.reflect.Person");
            System.out.println(pClass);

            //只能获取公共成员变量
            Field[] fields = pClass.getFields();
            for (Field field : fields) {
                System.out.println(field.toString());
            }

            System.out.println("=======================================");

            //可以获取私有成员变量(包括公共成员变量)
            Field[] declaredFields = pClass.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                System.out.println(declaredField.toString());
            }

            System.out.println("=======================================");

            //newInstance()方法是调用默认的构造方法实例化一个对象
            Object p = pClass.newInstance();

            //根据名字获取公有成员变量并操作
            Field age1 = pClass.getDeclaredField("age");
            System.out.println(age1);

            //用set方法来设置值
            age1.set(p,18);
            //用get方法来获取值
            System.out.println(age1.get(p));

            System.out.println("=======================================");

            //根据名字获取私有成员变量,需要将暴力破解
            Field name1 = pClass.getDeclaredField("name");
            System.out.println(name1);
            //需将这个值设置为true才能操作私有变量
            name1.setAccessible(true);
            name1.set(p,"huge");
            System.out.println(name1.get(p));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值