【Java 反射】Java反射的学习

1 参考资料

  1. https://how2j.cn/k/reflection/reflection-class/108.html 一个比较全面的Java学习教程(这里用下人家的代码)
  2. Java编程思想

2 反射的由来

假设自己从磁盘文件或者网络获取了一串字节,且被告知这串字节代表了一个类。然后,我们如何去使用这样的一个类?
解决办法----反射(Class类和java.lang.reflect类对反射概念进行了描述)

3 反射和RTTI的区别

很简单,RTTI是在编译时打开和检查.class文件,反射是在运行时打开和检查.class文件。

4 反射能干嘛

4.1 获取Class对象

这个就是三种方法获取Class对象。
点它进去看详细介绍
不点这也有图( ̄▽ ̄)
在这里插入图片描述

4.2 创建对象

首先我们这里得现有一个定义好的Hero类。

public class Hero {
    public String name;
    public float hp;
    public int damage;
    public int id;

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

    }
    public Hero(String string) {
        name =string;
    }

    @Override
    public String toString() {
        return "Hero [name=" + name + "]";
    }
    public boolean isDead() {
        // TODO Auto-generated method stub
        return false;
    }
    public void attackHero(Hero h2) {
        System.out.println(this.name+ " 正在攻击 " + h2.getName());
    }

}

然后我们来测试下,用反射方法创建新的Hero对象

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ReflectDemo {
    public static void main(String[] args) throws IllegalAccessException,
            InstantiationException,
            NoSuchMethodException,
            InvocationTargetException {

        // Class 直接创建实例,但是该类必须要有一个无参的默认构造函数
        //只能反射无参的构造器,需要构造器可见;
        Class<Hero> heroClass = Hero.class;
        Hero hero = heroClass.newInstance();
        // 通过类的构造器创建实例,可以反射任何构造器,可以反射私有构造器
        Constructor<Hero> heroConstructor = heroClass.getConstructor(String.class);
        Hero hero1 = heroConstructor.newInstance("CC");

        System.out.println(hero.toString());
        System.out.println(hero1.toString());
    }
}

瞅瞅结果
在这里插入图片描述

4.3 修改属性值
    Class<Hero> heroClass = Hero.class;
    Hero hero = heroClass.newInstance();

    hero.setName("CC");
    System.out.println("hero's Name is "+hero.getName());
    Field field = heroClass.getField("name");
    field.set(hero,"GG");
    System.out.println("hero's Name is "+hero.getName());

结果,
在这里插入图片描述
PS:getField 只能获取public的,包括从父类继承来的字段。
getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段。
(注: 这里只能获取到private的字段,但并不能访问该private字段的值,除非加上setAccessible(true))

4.4 调用方法

同理,这边也很简单了

 Class<Hero> heroClass = Hero.class;
        Hero h = heroClass.newInstance();

        // 获取这个名字叫做setName,参数类型是String的方法
        Method m = heroClass.getMethod("setName", String.class);
        // 对h对象,调用这个方法
        m.invoke(h, "盖伦");
        // 使用传统的方式,调用getName方法
        System.out.println("hero's name is "+h.getName());

结果
在这里插入图片描述

5 ending 反射机制在我们平常的开发中自己使用得比较少,但是在支持其他特性中用的比较多。Spring就是一个例子,由于现在还没学,就不展开讲了。最后,文章若有问题欢迎指正~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值