在通用Java Bean上设置属性

时间:2012-01-04 05:14:46

标签: java javabeans

这可能吗?我正在使用以下代码从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吗?

3 个答案:

答案 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();
            }
        }           
    }
}