java反射机制的应用(问题记录)
2017-02-21 18:14
232 查看
今天在写一个添加平台接口的时候,用到了java反射机制,场景是在Linux服务器上有一个保存方法接口(save),如下所示
@Transactional @Override publicIntegersave(LongmodelId,StringsysCode,StringuserId,Objectobject){ Field[]fields=object.getClass().getDeclaredFields(); intnum=0; for(Fieldfield:fields){ logger.info("当前的反射字段是:"+field); } for(Fieldfield:fields){ ModelPropertymodelProperty=newModelProperty(); modelProperty.setModelProName(field.getName()); List<ModelProperty>modelProperties=modelPropertyDao.getByCondition(modelProperty); InstanceDatainstanceData=newInstanceData(); if(modelProperties==null||modelProperties.size()==0){ modelProperty.setCreateTime(newDate()); modelProperty.setModelId(modelId); modelProperty.setModifyTime(newDate()); modelProperty.setCreator(userId); modelProperty.setPropertyType(field.getType().toString()); modelPropertyDao.save(modelProperty); instanceData.setModelProId(modelProperty.getModelProId()); }else{ instanceData.setModelProId(modelProperties.get(0).getModelProId()); } instanceData.setSyscode(sysCode); instanceData.setModelId(modelId); instanceData.setCreateTime(newDate()); instanceData.setModifyTime(newDate()); instanceData.setCreator(userId); Objectresult=getFieldValueByName(field.getName(),object); if(result!=null) instanceData.setInstanceValue(result.toString()); num+=instanceDataDao.save(instanceData); } returnnum; } privateObjectgetFieldValueByName(StringfieldName,Objecto){ try{ StringfirstLetter=fieldName.substring(0,1).toUpperCase(); Stringgetter="get"+firstLetter+fieldName.substring(1); Methodmethod=o.getClass().getMethod(getter,newClass[]{}); Objectvalue=method.invoke(o,newObject[]{}); logger.info("获取到的值是:"+value); returnvalue; }catch(Exceptione){ e.printStackTrace(); returnnull; } }
客户端调用服务器的这个接口,我开始传的是addPlatInfo.getClass,结果就是死活没有我定义的属性,都是些不认识的属性,这个问题纠结了很长时间。
@Override publicResultMapaddPlatform(StringplatformName,StringplatformImg,StringplatformIntroduce,String[]goodFields,StringuserId){ AddPlatInfoaddPlatInfo=newAddPlatInfo(); addPlatInfo.setPlatName(platformName); addPlatInfo.setImgUrl(platformImg); addPlatInfo.setPlatIntroduction(platformIntroduce); addPlatInfo.setExpertArea(getExpertArea(goodFields)); //test(addPlatInfo,userId); try{ intresult=instanceDataApi.save(SystemConstant.MODELID,SystemConstant.SYSCODE,userId,addPlatInfo); if(result==0){ returndealError(newResultMap(),"添加平台失败!"); } returndealOk(newResultMap(),"添加平台成功!"); }catch(Exceptione){ e.printStackTrace(); returndealError(newResultMap(),"添加平台失败!"); } }
后来请教别人才知道调用的时候不能用addPlatInfo.getClass()作为参数,下面我把追踪的数据贴出来。
1.刚定义完addPlatInfo时查看对象,如下图所示。
2.addPlatInfo.getClass()所得到的类的属性如下图所示,发现都是些父级类的属性,没有我们定义的那四个属性。
3.addPlatInfo.getClass().getClass()所得到的类的属性如下所示,这时我们看到的属性跟第2步看到的属性一样,只是属性值不一样。
看完了类,下面再看下反射得到的fields。代码如下:
Objectobj=addPlatInfo; Field[]fields=obj.getClass().getDeclaredFields();
获取到的fields如下图所示:
再多调一次getClass()
Field[]fieldss=obj.getClass().getClass().getDeclaredFields();
这时再看看fieldss,发现这时获取的字段已经不是我们想要的字段了,因此,客户端在传参数是一定是直接传对象本身,不能传addPlatInfo.getClass()!!!
另外,需要说明的是,反射的对象只有在本工程下可以被识别,如果从客户端传递对象到服务端,服务端要想反射获取值的话,必须也知道这个对象才行!(当然,可以把这个对象放到一个公共的Jar包中,然后客户端和服务端都引用这个jar包也可以)
相关文章推荐
- Initramfs应用问题记录
- ucenter添加应用通信失败问题记录
- iOS企业发布问题记录一(为什么iOS的应用安装到一半时提示"无法下载应用程序"?)
- springmvc 应用 Velocity 问题记录
- 技术记录---杀死应用进程账号数据被清空问题
- eclipse部署tomcat应用问题记录
- Tpshop 插件、多商户版、缓存各种问题处理与应用记录
- css高级应用及问题记录(持续更新)
- 需要这样一个记事本-11 完成端口IOCP应用问题记录
- 2个应用Log4j日志记录同一目录下问题
- martini应用搭建问题记录一--重复类载入
- 《解决问题1000.1》又是I2C驱动问题,产品应用上一个问题,非常简单,也比较典型,记录一下
- 移动应用web适配开发过程中遇到的问题记录
- JBoss应用遇到问题记录
- Android应用混淆问题记录
- 记录C#开发遇到的问题和应用经验
- 记录解决UCenter 1.6 DISCUZ 3.1 和 ECmall 2.3 中EC点击退出无法同步其他应用退出的问题
- 最近做了一个iOS小应用,记录下遇到的问题以及解决方法
- VS2010-C#应用开发问题记录
- 微信分享(修改应用名称)问题记录