反射超详细(一)—— 反射基础

不求流芳百世,只求口碑载道

写在前面的话

反射作为java的核心基础之一是肯定要掌握的,虽然业务开发用的不多但是不代表它不重要。正所谓手中有粮心中不慌,本系列文章主要就是为了巩固和夯实反射知识点,为之后学习框架的编写打好基础。

一、反射相关

1、反射概念

反射是Java被视为动态语言的关键,反射机制允许程序在执行期间借助Reflection API获取任何类的内部信息,并能直接操作任意对象的内部属性及方法。
加载完类之后,在堆内存的方法区会产生一个Class类型的对象(一个类只有一个Class对象),这个对象包含了完成的类的结构信息,我们可以通过这个对象看到类的结构。

正常方式是:引入需要的包,通过new实例化,得到实例化的对象。
反射方式是:通过调用实例化对象的getClass()方法得到对象的全类名。

2、反射框架中常见方法

// 代表一个类
java.lang.Class
// 调用class对象的newInstance()返回一个对象实例
java.lang.Class#newInstance
// 代表类的方法,包括该类和超类中那些公共成员方法
java.lang.Class#getMethods
// 代表类的方法,包括公共、保护、默认(包)访问和私有方法,不包含超类的方法
java.lang.Class#getDeclaredMethods
// 代表类的字段,获得类的所有的public字段,包括父类
java.lang.Class#getFields
// 代表类的字段,获得类的所有声明的字段,即包括public、private、default、protected 不包括父类
java.lang.Class#getDeclaredFields
// 返回所有的包括私有构造方法,不包含超类
java.lang.Class#getDeclaredConstructors
// 只返回public访问权限的构造方法,不包含超类
java.lang.Class#getConstructors

二、反射相关API

1、获取Class类实例三种方法

// 1. 直接调用类的class属性获取
Class aClass = DictResponse.class;
// 2. 已知一个类的实例,调用该实例的getClass()获取
DictResponse response = new DictResponse();
Class<? extends DictResponse> responseClass = response.getClass();
// 3. 已知类的全类名 调用Class的类方法forName()获取
Class<?> aClass1 = Class.forName("reflect.DictResponse");

打印出hashcode,发现一致。所以验证了前面说的一个类只有一个Class对象。

2、获取类的运行时结构

写一个实体类DictResponse

public class DictResponse{

    private Long id;

    private String name;

    private BigDecimal price;

	// 忽略构造函数和get,set方法
}
// reflect.DictResponse
// DictResponse
DictResponse dictResponse = new DictResponse();
Class<? extends DictResponse> aClass = dictResponse.getClass();
System.out.println(aClass.getName());
System.out.println(aClass.getSimpleName());

// 打印出所有方法(构造方法,get,set,toString)
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
    System.out.println(declaredMethod);
}

// 打印该类所有属性
// private java.lang.Long reflect.DictResponse.id
// private java.lang.String reflect.DictResponse.name
// private java.math.BigDecimal reflect.DictResponse.price
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
    System.out.println(declaredField);
}

注意:这里发现打印出来的属性全部是private,这时仅仅是能拿到属性但是不可以操作!

// 我们给id属性set值,会报异常
// Class reflect.ReflectMain can not access a member of class reflect.DictResponse with modifiers "private"
// declaredField.setAccessible(true) 设置暴力破解修饰符使得可以访问并使用私有属性 
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
	//declaredField.setAccessible(true);
    if (declaredField.getType().equals(Long.class)) {
        declaredField.set(dictResponse, 1L);
        System.out.println(dictResponse.toString());
    }
}

先到此为止,后续会有反射获取泛型结构信息及invoke()方法说明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值