浅谈Java反射机制

Java反射机制

在我们了解Java反射之前先思考什么是正射,即程序正常运行的过程。

正射:程序在编译之前就已经被Java虚拟机加载,加载完了所有需要的类。

反射:在编译时并不知道哪个类被加载,在运行时才加载、调用。

总结下来什么是反射机制:在程序运行时,才会动态获取类的完整结构信息以及调用对应方法的功能。

Java反射常用的类

Class类:反射的核心类,所有操作都是围绕该类来生成的,通过Class类可以获取类的属性、方法。
Field类:表示类的属性。
Method类:表示类的方法。
Constructor类:表示类的构造方法。

反射的应用

首先创建一个Person类

package entity;

public class Person {
    private String name;
    public int age;
    private char gender;

    public Person() {}

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

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

    private void welcome(String tips){
        System.out.println(tips);
    }

    public void happy(String name,int age,char gender){
        System.out.println(name + age + gender);
    }

    private int age(int num){
        return num;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender=" + gender +
                '}';
    }
}

一、获取Class对象
1、调用对象的getClass方法

Person p = new Person();
Class c = p.getClass();
//注:getClass()是Object类中的一个方法,该方法可以返回该对象所属类对应的Class对象。

2、调用类的class属性

Class c = Person.class;
//注:调用类的class属性可以获取该类对应的Class对象,但是要在编译期间就知道类的名称。

3、使用Class类的forName静态方法

Class c = Class.forName("entity.Person");
//注:Class类的forName()方法也可以获取对应的Class对象,该方法需要传入字符串参数,该字符串参数的值是类的全名,要在类名前加完整的包名。

补:获取父类对象
假设Person类是某个类的子类,则我们可以通过Person类来获取其父类的Class对象

Class c1 = c.getSuperclass();			//c为Person的Class对象

二、创建对象
首先获取Person的Class对象,采用上述方法中的其中一种即可

Class c = Person.class;

1、使用Class对象的newInstance方法来创建对象

Person p = (Person)c.newInstance();
//注:该方式需要该Class对象的对应类有默认的构造方法,执行newInstance()方法实际就是利用默认的构造方法来创建类的实例。

2、使用Constructor对象的newInstance方法创建对象

Constructor t = c.getConstructor(String.class,int.class,char.class);
Person p = (Person) t.newInstance("任",18,'男');
System.out.println(p.toString());
//通过这种方式可以选择使用某个类的指定构造方法来创建实例,需要提供给getConstructor()参数类型

三、访问Class对应类所包含的属性

Class c = Person.class;													//获取类的Class对象
//Field[] fields = c.getFields();										//getFields()获取Person对象的所有public属性
Field[] fields = c.getDeclaredFields();									//getDeclaredFields()获取所有属性,无论私有公有
for (int i = 0; i < fields.length; i++) {
    System.out.println(fields[i].getName());							//获取属性名
    System.out.println(Modifier.toString(fields[i].getModifiers()));	//获取属性修饰符
}
//Field field = c.getField("age");										//获取指定的public属性,age为属性名
Field field = c.getDeclaredField("name");								//获取指定的属性,无论公有私有,getDeclaredField("属性名")
field.setAccessible(true);												//当获取私有属性时,必须将setAccessible()方法设置为true,setAccessible()对获取到的属性设置访问权限
Person p = new Person();
field.set(p,"张三");														//对属性进行赋值
System.out.println(p.toString());

四、访问Class对应类所包含的构造方法

Class c = Person.class;													//获取类的Class对象
Constructor[] constructors = c.getConstructors();						//获取所有public构造方法
//Constructor[] constructors = c.getDeclaredConstructors();				//获取Person类中的所有构造方法
for (int i = 0; i < constructors.length; i++) {
    System.out.println(constructors[i].getName());
    System.out.println(constructors[i].getModifiers());
    Class[] parameterTypes = constructors[i].getParameterTypes();		//获取参数类型
    for (int j = 0; j < parameterTypes.length; j++) {
        System.out.println(parameterTypes[i].getName());				//获取参数名
    }
    System.out.println();
}
//Constructor constructor = c.getConstructor();							//获取public构造方法,支持有参无参,想指定什么构造方法,只需将对应参数填入即可
//getDeclaredConstructor()获取Person类任意一个构造方法,不论公私
Constructor constructor = c.getDeclaredConstructor(String.class,int.class,char.class);
constructor.setAccessible(true);										//访问私有,参数为true,允许访问
Person person = (Person) constructor.newInstance("任",24,'男');			//通过构造方法的newInstance方法进行赋值
System.out.println(person.toString());

五、访问Class对应类所包含的非构造方法(普通方法)

Person person = new Person();
Class t = person.getClass();
Method[] methods = t.getMethods();										//获取所有public方法
//Method[] methods = t.getDeclaredMethods();							//获取所有方法
for (int i = 0; i < methods.length; i++) {
    System.out.println(Modifier.toString(methods[i].getModifiers()));
    System.out.println(methods[i].getName());
    Class[] parameterTypes = methods[i].getParameterTypes();
    for (int j = 0; j < parameterTypes.length; j++) {
        System.out.println(parameterTypes[j].getName());
    }
    System.out.println();
}
//Method method = t.getMethod("happy", String.class,int.class,char.class);
//getMethod()获取指定public方法,happy为方法名,后面为参数
Method method = t.getDeclaredMethod("welcome", String.class);			//getDeclaredMethod()获取指定方法,无论公私
System.out.println(Modifier.toString(method.getModifiers()));
method.setAccessible(true);
method.invoke(person,"阿门");											//invoke()方法进行赋值
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值