Java中的反射以及使用方法

一. 简介

在程序运行阶段, 动态获取一个类中的属性或者方法, 把这种机制成为反射机制. 可以说, 没有反射就没有Java的任何框架

二. 应用

产生对象

假设有一个Student对象

public class Student {
    private String name;
    public int age;
    static int nationality;

    public Student() {
        System.out.println("Student类的无参构造");
    }
    Student(String name) {
        System.out.println("Student的一个参数的有参构造");
    }
    private Student(String name,int age) {
        this.name = name;
        this.age = age;
        System.out.println("Student类的有参构造");
    }
    public void fun(int[] arr) {
        System.out.println("public权限的成员方法 fun");
    }
    private String getName() {
        return this.name;
    }
    public static void test() {
        System.out.println("Student的静态方法test");
    }
}

*获取class对象

要用反射操作某个类, 需要先获取该类的class对象
获取class对象的三个方式:
Class<类名> cls = (Class<类名>) Class.forName("包名.类名")
Class<类名> cls = Student.class
Class<类名> cls = (Class<类名>) new Student().getClass()
例如Student对象的获取:

Class<Student> cls1 = (CLass<Student>) Class.forName("reflect.Student");
Class<Student> cls2 = Student.class;
Class<Student> cls3 = (Class<Student>) new Student().getClass();

不过一般使用第②个方法,写法简单

通过反射产生对象

Class类的newInstance()方法

例如对于Student类: Student stu1 = cls2.newInstance();
默认调用的是无参构造, 而且该构造方法必须是public权限

通过Constructor调用构造方法

Constructor类是Java中利用反射操作构造方法的类
两个方法:
getConstructor(参数): 获取该类的所有(加s)public权限的构造方法
getDeclaredConstructor(参数): 获取该类的所有(加s)权限的构造方法, 包括private, default权限

Class<Student> cls2 = Student.class;
//获取该类的所有权限的构造方法
Constructor<Student>[] constructors = cls2.getDeclaredConstructors();
//获取私有的有参构造:private Student(String name,int age),参数对应上
Constructor<Student> constructor = cls2.getDeclaredConstructor(String.class, int.class);

//破坏封装性,调用私有构造方法
constructor.setAccessible(true);
//要用下面的方法, 不可以用new Student()
Student stu2 = constructor.newInstance("小明",18);

通过反射操作类中方法

getMethod(): 获取所有(加s)公共方法
getDeclaredMethod(): 获取类中所有(加s)方法

//接着上面
Method[] methods = cls2.getDeclaredMethods();
//此时数组里就包含了所有的方法以及权限

//调用普通方法与静态方法
//调用普通方法都要产生对象
Student student = cls2.newInstance();
//获取方法(参数1:方法的名字, 后面的参数就是方法的参数)
Method methodFun = cls2.getDeclaredMethod("fun",int[].class);
//调用方法(参数1是对象,后面是方法参数)
methodFun.invoke(student, new int[]{1,2,3,4,5});

//通过反射调用静态方法
Method methodTest = cls2.getDeclaredMethod("test");
//不需要对象即可调用
methodTest.invoke(null);

通过反射操作类中属性

getField(): 获取所有(加s)public方法
getDeclaredField(): 获取所有(加s)方法, 包括private

//获取class对象
Class<Student> cls = Student.class;
//实例化对象
Student stu = cls.newInstance();

//用cls.getDeclaredField()获取私有属性
Field nameField = cls.getDeclaredField("name");
//设置name属性为可访问
nameField.setAccessible(true);
//修改该对象的该属性
nameField.set(stu,"bob");

//获取public属性
Field ageField = cls.getField("age");
//修改该对象的该属性
ageField.set(stu,88);

//获取静态属性
Field nationalityField = cls.getField("nationality");
//修改属性
nationalityField.set(null,"USA");

//经过检查,修改都生效了
System.out.println(Student.nationality);
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值