1.反射机制说明
java的反射机制允许程序在运行时检查和操作类、方法、字段等结构。通过反射,可以动态地创建对象、调用方法、获取/设置字段的值,而无需在编译时确定这些操作。
反射的核心类是java.lang.reflect
包中的method
、field
和constructor
等。使用反射需要注意性能开销和安全性问题。
- 获取类的class对象
class<?> clazz = myclass.class;
- 实例化对象
myclass myobject = (myclass) clazz.getdeclaredconstructor().newinstance();
- 获取和调用方法
method method = clazz.getdeclaredmethod("methodname", parametertypes); method.setaccessible(true); // 如果方法是private的,需要设置accessible为true object result = method.invoke(myobject, args);
- 获取和设置字段值
field field = clazz.getdeclaredfield("fieldname"); field.setaccessible(true); // 如果字段是private的,需要设置accessible为true object value = field.get(myobject); field.set(myobject, newvalue);
- 操作构造函数
constructor<?> constructor = clazz.getdeclaredconstructor(parametertypes); constructor.setaccessible(true); // 如果构造函数是private的,需要设置accessible为true myclass myobject = (myclass) constructor.newinstance(args);
2.vo,dto,po的说明
vo(value object)值对象
vo就是展示用的数据,不管展示方式是网页,还是客户端,还是app,只要是这个东西是让人看到的,这就叫vo,这个大家都很理解,反正就是我们的接口返回给前端的对象都是用vo来返回,跟dto不一样的是,vo是我们返回给前端,dto是我们从前端接收的时候用的,即一个是入参,一个是返回结果
dto(data transfer object)数据传输对象
这个传输通常指的前后端之间的传输
dto是一个比较特殊的对象,他有两种存在形式:
- 一种是前端和后端交互所使用的对象
- 另一种是微服务之间的一种传输对象,我们一般也是用dto来进行传输
po(persistant object)持久对象
po比较好理解,简单说po就是数据库中的记录,一个po的数据结构对应着库中表的结构,表中的一条记录就是一个po对象,通常po里面除了get,set之外没有别的方法,对于po来说,数量是相对固定的,一定不会超过数据库表的数量,等同于bo,这俩概念是一致的
3.beanutils的实现原理
在后端的各个层中进行数据传输时,经常使用beanutils进行bean的拷贝,其实现原理就是通过java的放射机制实现。
package org.springframework.beans; private static void copyproperties(object source, object target, @nullable class<?> editable, @nullable string... ignoreproperties) throws beansexception { assert.notnull(source, "source must not be null"); assert.notnull(target, "target must not be null"); class<?> actualeditable = target.getclass(); if (editable != null) { if (!editable.isinstance(target)) { throw new illegalargumentexception("target class [" + target.getclass().getname() + "] not assignable to editable class [" + editable.getname() + "]"); } actualeditable = editable; } propertydescriptor[] targetpds = getpropertydescriptors(actualeditable); list<string> ignorelist = ignoreproperties != null ? arrays.aslist(ignoreproperties) : null; propertydescriptor[] var7 = targetpds; int var8 = targetpds.length; for(int var9 = 0; var9 < var8; ++var9) { propertydescriptor targetpd = var7[var9]; method writemethod = targetpd.getwritemethod(); if (writemethod != null && (ignorelist == null || !ignorelist.contains(targetpd.getname()))) { propertydescriptor sourcepd = getpropertydescriptor(source.getclass(), targetpd.getname()); if (sourcepd != null) { method readmethod = sourcepd.getreadmethod(); if (readmethod != null) { resolvabletype sourceresolvabletype = resolvabletype.formethodreturntype(readmethod); resolvabletype targetresolvabletype = resolvabletype.formethodparameter(writemethod, 0); boolean isassignable = !sourceresolvabletype.hasunresolvablegenerics() && !targetresolvabletype.hasunresolvablegenerics() ? targetresolvabletype.isassignablefrom(sourceresolvabletype) : classutils.isassignable(writemethod.getparametertypes()[0], readmethod.getreturntype()); if (isassignable) { try { if (!modifier.ispublic(readmethod.getdeclaringclass().getmodifiers())) { readmethod.setaccessible(true); } object value = readmethod.invoke(source); if (!modifier.ispublic(writemethod.getdeclaringclass().getmodifiers())) { writemethod.setaccessible(true); } writemethod.invoke(target, value); } catch (throwable var18) { throw new fatalbeanexception("could not copy property '" + targetpd.getname() + "' from source to target", var18); } } } } } } }
4.beanutils的简单示例
public class beantoolutils { public static void copy(object source, object target) throws exception { class<?> sourceclass = source.getclass(); class<?> targeteclass = target.getclass(); field[] fields = targeteclass.getdeclaredfields(); // 输出字段信息 for (field field : fields) { string name = field.getname(); if ("serialversionuid".equals(name)) { continue; } string gettername = "get" + name.substring(0, 1).touppercase() + name.substring(1); string settername = "set" + name.substring(0, 1).touppercase() + name.substring(1); method getmethod = sourceclass.getmethod(gettername); if(!objectutils.isempty(getmethod)){ object val = getmethod.invoke(source); method setmethod = targeteclass.getmethod(settername,field.gettype()); setmethod.invoke(target, val); } } } }
说明:
获取目标bean的class对象,通过class对象获取目标bean的所有属性,循环属性信息,获取属性的get和set方法,执行来源bean的get方法获取属性值,执行目标bean的set方法,设置属性值,完成bean的赋值操作。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论