反射和内省的介绍和操作

本文详细介绍了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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值