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的赋值操作。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论