这可能吗?我正在使用以下代码从JSON字符串创建一个对象:
String obj = new Gson().toJson(jsonArray.getJSONObject(i));
String className = getClassName(jsonArray.getJSONObject(i));
Class targetClass = null;
try {
targetClass = Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//Create Object
Object data = new Gson().fromJson(obj, targetClass);
然后我做一些数据库的东西,得到一个返回键值,我想使用它的setId()setter在bean对象上设置该键,但我不想将特定类型的对象强制转换为通用对象,因为这需要我多次重复完全相同的代码才能转换对象。
key = contactsListDAO.manageDataObj(data, sql, true);
((PhoneNumber) data).setId(key);
我可以使用某种if语句来检查对象是否包含id属性,然后在不必强制转换的情况下在通用对象上设置id吗?
答案 0 :(得分:0)
反思可以做到这一点,但我想也许在这里你应该做别的事情。 写一个效用函数
public static <T> T fromJson(String json, Class<T> clzz)
{
return (T) new Gson().fromJson(obj, targetClass);
}
然后你可以像这样调用它
PhoneNumber data = fromJson(obj, PhoneNumber.class);
不再转换。
编辑:如果使用“对象”是约束,则可以使用反射
public void setIdOnObject(Object obj, Object id)
{
try{
Method m = obj.getClass().getMethod("setId",id.getClass());
m.invoke(obj, id );
}catch(NoSuchMethodException e){ return false; } catch (InvocationTargetException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (IllegalAccessException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
这是我的一个工作示例,只是复制粘贴运行。
import java.lang.reflect.InvocationTargetException;
public class Reflection
{
public static void main( String[] args )
{
MyParent p = new MyParent();
setParentKey( p, "parentKey" );
MyObj o = new MyObj();
setParentKey( o, "myParentKey" );
setMyKey( o, "myKey" );
System.out.println( "p = " + p );
System.out.println( "o = " + o );
}
public static void invokeMethod( Object p, Object k, String methodName )
{
try
{
p.getClass().getMethod( methodName, k.getClass() ).invoke( p, k );
}
catch ( NoSuchMethodException e )
{
e.printStackTrace();
}
catch ( InvocationTargetException e )
{
e.printStackTrace();
}
catch ( IllegalAccessException e )
{
e.printStackTrace();
}
}
public static void setParentKey( Object p, Object k )
{
invokeMethod( p,k,"setParentKey" );
}
public static void setMyKey( Object p, Object k )
{
invokeMethod( p,k,"setMyKey" );
}
public static class MyParent
{
private Object parentKey;
public void setParentKey( String k )
{
parentKey = k;
}
@Override
public String toString()
{
return "MyParent{" +
"parentKey=" + parentKey +
'}';
}
}
public static class MyObj extends MyParent
{
private Object myKey;
public void setMyKey( String k )
{
myKey = k;
}
@Override
public String toString()
{
return "MyObj{" +
"myKey=" + myKey +
"} " + super.toString();
}
}
}
预期的输出是:
p = MyParent{parentKey=parentKey}
o = MyObj{myKey=myKey} MyParent{parentKey=myParentKey}
答案 1 :(得分:0)
如果您(如您所述)“多个bean类型”和“它们都具有id属性”,为什么不使用setId方法为bean定义公共接口?
你将获得你的bean并且只是转换到接口,这将是一种安全且面向对象的方法。这对你来说是一个可行的解决方案吗?
答案 2 :(得分:0)
这是我的工作代码。出于某种原因,我永远无法使用class.getMethod()找到方法,所以我不得不遍历一个方法数组并将名称与我知道存在的setId方法相匹配。从那里使用invoke是正确设置属性的关键。
public void setIdOnObject(Object obj, int id, Class<?> targetClass) {
Method[] methods = targetClass.getMethods();
for(Method i : methods) {
if(i.getName().equals("setId")) {
try {
i.invoke(obj, id);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}