Java 的反射机制

文章目录[隐藏]

示例程序

package top.sunriseydy.example.reflectDemo;

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

/**
 * 定义一个 Person 类
 */
class Person {
    public String  name;
    public int age;
    private String sex; // 私有访问权限

    public Person() {
    }

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

    private Person(String name) { // 私有的构造方法
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public String getSex() {
        return sex;
    }

    private void setSex(String sex) { // 私有的方法
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }
}
/**
 * User: sunriseydy
 * 2018-7-11 14:11
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Class<?> cls; // 声明一个 Class 类的对象,参数<?> 表明将被反射的类的类型未知
        cls = Class.forName("top.sunriseydy.example.reflectDemo.Person"); // 通过类名,得到 Class 对象的方法三
        cls = top.sunriseydy.example.reflectDemo.Person.class; // 通过类名,得到 Class 对象的方法二
        System.out.println(cls); // 输出反射后的类名
        Person p1 = (Person) cls.newInstance(); // 直接使用反射实例化一个对象
        cls = p1.getClass(); // 通过对象,得到 Class 对象的方法一
        System.out.println("直接通过反射实例化一个对象 p1: " + p1);

        Constructor<?> constructor = cls.getConstructor(); // 通过反射得到 Person 类的默认构造方法
        Person p2 = (Person) constructor.newInstance(); // 利用得到的默认构造方法实例化一个对象
        System.out.println("调用默认的构造方法 p2: " + p2);

        Constructor<?> constructor1 = cls.getConstructor(String.class, int.class, String.class); // 通过反射得到带有参数的构造方法
        Person p3 = (Person) constructor1.newInstance("张三",21,"男"); // 利用得到的带参数的构造方法实例化一个对象
        System.out.println("调用带参数的公有构造方法 p3: " + p3);

        Constructor<?> constructor2 = cls.getDeclaredConstructor(String.class); // 通过反射得到私有的构造方法
        constructor2.setAccessible(true); // 设置可访问的权限,若注释掉该行则下一行在运行时会报错
        Person p4 = (Person) constructor2.newInstance("李四"); // 使用私有的构造方法实例化对象
        System.out.println("调用私有的构造方法 p4: " + p4);

        Field[] fields = cls.getDeclaredFields(); // 获取 Person 类声明的所有属性,若使用 getFields() 方法则无法获取私有属性
        System.out.println("获取 Person 类声明的所有属性:");
        for (int i = 0; i < fields.length; i++) {
            System.out.println(fields[i]);
        }

        Method[] methods = cls.getDeclaredMethods();
        System.out.println("获取 Person 类声明的所有方法:");
        for (int i = 0; i < methods.length; i++) {
            System.out.println(methods[i]);
        }

//        Object object = null;
        Method setAge = cls.getMethod("setAge", int.class); // 通过反射得到类方法
        Method setSex = cls.getDeclaredMethod("setSex", String.class); // 得到私有的方法
        setSex.setAccessible(true); // 同样设置访问权限

        setAge.invoke((Object)p4,23); // 调用得到的方法
        System.out.println("修改年龄后的 p4: " + p4);

        setSex.invoke((Object) p4,"女"); // 调用私有的类方法
        Method getSex = cls.getMethod("getSex"); // 得到无参的类方法
        System.out.println("修改性别后 p4 的性别:" + getSex.invoke((Object) p4));

        Field personSexField = cls.getDeclaredField("sex"); // 得到私有的类属性
        personSexField.setAccessible(true); // 设置访问权限
        System.out.println("直接访问 p4 的性别:" + personSexField.get((Object) p4));
    }
}

运行结果:

直接通过反射实例化一个对象 p1: Person{name='null', age=0, sex='null'}
调用默认的构造方法 p2: Person{name='null', age=0, sex='null'}
调用带参数的公有构造方法 p3: Person{name='张三', age=21, sex='男'}
调用私有的构造方法 p4: Person{name='李四', age=0, sex='null'}
获取 Person 类声明的所有属性:
public java.lang.String top.sunriseydy.example.reflectDemo.Person.name
public int top.sunriseydy.example.reflectDemo.Person.age
private java.lang.String top.sunriseydy.example.reflectDemo.Person.sex
获取 Person 类声明的所有方法:
public java.lang.String top.sunriseydy.example.reflectDemo.Person.toString()
public java.lang.String top.sunriseydy.example.reflectDemo.Person.getName()
public void top.sunriseydy.example.reflectDemo.Person.setName(java.lang.String)
public int top.sunriseydy.example.reflectDemo.Person.getAge()
public void top.sunriseydy.example.reflectDemo.Person.setAge(int)
private void top.sunriseydy.example.reflectDemo.Person.setSex(java.lang.String)
public java.lang.String top.sunriseydy.example.reflectDemo.Person.getSex()
修改年龄后的 p4: Person{name='李四', age=23, sex='null'}
修改性别后 p4 的性别:女
直接访问 p4 的性别:女

 

总结

关于 Java 的反射机制就先介绍到这里,反射机制在 Java 中是比较难但是很重要的一部分,在 Java 的一些框架中大量用到,当然不仅仅只有我介绍的这几个功能,反射机制还有很多很多神奇的功能等着我们去探索。

参考

JDK 6 中文在线 API:http://tool.oschina.net/apidocs/apidoc?api=jdk-zh

JDK 6 中文 API & JDK 8 英文 API 下载:https://dl.sunriseydy.top/学习相关/JDKAPI18CN.zip


版权说明:
作品 sunriseydy 采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
文章内容如未说明均为原创,欢迎转载,但请注明原作者(sunriseydy)和原文链接(https://blog.sunriseydy.top/technology/code/java/java-reflect/)
部分来自互联网的文章,如有侵权,请联系我,24小时内删除,谢谢

手机打开扫一扫即可访问本页面

感谢您的支持,SunriseYDY 会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

日出一点一 | 在探索的路上永不止步

分享到微博 分享到QQ 微信赞赏 在手机上阅读 点赞 0

页面: 1 2

评论一下呗亲

电子邮件地址不会被公开。 必填项已用*标注