反射和内省的介绍和操作

本文详细介绍了Java中的反射机制,包括为何需要反射、如何获取及调用构造器和方法,以及字节码对象的获取方式。同时,内省技术也被讲解,用于简化JavaBean属性的getter和setter方法调用,提供了更便捷的操作属性的方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、反射

1.为什么需要反射?

因为我们在某些情况不知道传入的参数的真是类型,所以需要用反射来操作,获取到真实类型,进而去调用我们需要的构造器、方法、字段等。

2.获取字节码对象

①使用类的全限定名来获取字节码对象
Class clz = Class.forName("com.wjw.class._01_test.Person");
②使用对象来获取字节码对象
Person p = new Person();
Class clz = p.getClass();
③使用类名的方式来获取字节码对象
Class clz = Person.class;

3.使用字节码对象获取构造器

①获取所有构造器
Construtor[] cs = clz.getConstrutors();
②获取所有构造器(包括私有化构造器)
Construtor[] dcs = clz.getDeclaredConstrutors();
③获取指定构造器(里面的参数传入的是构造器参数类型的类对象)
Construtor c = clz.getConstrutor(String.class,Integer.class);
④获取指定的私有化构造器
Construtor dc = clz.getDeclaredConstrutor(String.class);

4.调用构造器

①调用指定构造器
Person p = c.getInstance("猪八戒",18);
②调用指定的私有化构造器
dc.setAccessible(true);
Person p = dc.getInstance("杨戬");

注意:需要将私有化的设置成可以访问才能进行调用

③直接调用无参构造器生成对象(类必须要有无参构造器)
Person p = clz.newInstance();

5.获取和调用方法

①获取所有方法
Method[] ms = clz.getMethods();

注意:这里获取的所有方法包括父类继承下来的方法

②获取本类中的所有的方法
Method[] dms = clz.getDeclaredMethods();

注意:这里获取的方法是本类的公共和私有方法

③获取指定的方法
Method m = clz.getMethod("方法名",参数列表的对象);
Method m = clz.getMethod("get",String.class);
④获取指定私有化方法
Method dm = clz.getDeclaredMethod("set",Integer.class);
⑤调用公共方法
Person p = clz.newInstance();
m.invoke(p,"张三");
⑥调用私有化方法
Person p = clz.newInstance();
dm.setAccessible(true);
dm.invoke(p,18);

二、内省

1.内省的作用

我们在用反射调用方法时非常的繁琐,如果想调用getter、setter方法时,还需要写两次繁琐的操作,因此SUN公司提供了一套操作JavaBean属性的API,方便我们去调用getter、setter方法

2.属性

前面是get、set的方法后面的名字就是属性

3.使用内省操作JavaBean

①将JavaBean转为BeanInfo
Class<Person> clz = Person.class;
Person p = clz.newInstance();
BeanInfo bif = Introspector.getBeanInfo(clz,Object.class);

注意:第二个参数的作用是“终点”,这样就不会获取到Object中的属性

②获取所有属性
PropertyDescriptor[] pds = bif.getPropertyDescriptors();
③获取属性的名字、类型、setter、getter方法
for (PropertyDescriptor pd : pds) {
	pd.getName();
	pd.getPropertyType();
	
	pd.getWriteMethod();
	pd.getReadMethod();
}
④案例:调用setter方法中的属性为name进行设置值
if ("name".equals(pd.getName())) {
	pd.getWriteMethod.invoke(p,"庞德");
}
⑤案例:调用getter方法中的属性为name进行获取值
if ("name".equals(pd.getName())) {
	Object name = pd.getReadMethod.invoke(p);
	System.out.println(name);
}
### Java 内省反射的概念及用法 #### 什么是反射反射Java 中的一种强大机制,允许程序在运行时动态地获取类的信息,并通过这些信息操作类的属性方法。这意味着开发者可以在不知道具体类名的情况下,加载并实例化某个类的对象,调用其方法或者修改其字段值[^4]。 以下是使用反射的一个简单示例: ```java import java.lang.reflect.Method; public class ReflectionExample { public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("java.util.ArrayList"); Method[] methods = clazz.getDeclaredMethods(); System.out.println("Methods in ArrayList:"); for (Method method : methods) { System.out.println(method.getName()); } } } ``` 这段代码展示了如何利用 `Class` 类以及它的静态方法 `forName()` 来加载指定名称的类,并通过该类对象获得所有的声明方法列表。 --- #### 什么是内省内省是基于反射实现的技术,主要针对 JavaBeans 进行设计。它提供了一种更简便的方式来访问操作 JavaBean 的属性及其对应的 getter setter 方法。即使某些属性可能不存在实际定义(即只有 get 或 set 方法),内省仍然会将其视为有效属性[^3]。 下面是一段展示如何使用内省技术的例子: ```java import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; public class IntrospectorExample { public static void main(String[] args) { try { PropertyDescriptor descriptor = new PropertyDescriptor("name", SampleBean.class); Object beanInstance = new SampleBean(); String oldValue = (String)descriptor.getReadMethod().invoke(beanInstance); // 调用getter System.out.println("Old Value: " + oldValue); descriptor.getWriteMethod().invoke(beanInstance, "New Name"); // 调用setter String newValue = (String)descriptor.getReadMethod().invoke(beanInstance); System.out.println("New Value: " + newValue); } catch (IntrospectionException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } static class SampleBean { private String name = "Default"; public String getName() { return this.name; } public void setName(String value) { this.name = value; } } } ``` 此例子说明了如何借助 `PropertyDescriptor` 对象读取或写入特定属性值的过程。 --- #### 反射 vs 内省 尽管两者都涉及到了对类结构的操作,但它们之间存在显著区别: - **适用范围**:反射适用于任何类型的类;而内省专用于处理遵循 JavaBean 规范的类。 - **易用程度**:由于内省封装了许多底层细节,因此对于标准 JavaBean 更加友好且易于上手。 - **性能影响**:无论是反射还是内省,在频繁使用的场景下都会带来一定的性能开销,应谨慎评估是否必要采用此类方式解决问题。 --- #### 总结 Java 提供了两种不同的元编程工具——反射内省。前者提供了极大的灵活性,能够适应各种复杂需求;后者则专注于简化常见的任务流程,特别是围绕着 JavaBeans 设计模式展开的工作流。理解两者的差异有助于选择最适合当前项目的解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值