您的位置:首页 > 编程语言 > Java开发

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包也可以)

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: