2

次のように、2つのクラスがあります。

public class Person {
    private String dob;
    private PersonName personName;
}

public class PersonName {
    private String firstName;
    private String lastName;
}

Java Reflection を使用してこれらの値を動的に設定しています。

まず、 のインスタンスを作成し、Personの値を設定しますdob。その後、 にPersonName値を設定する必要がありますPerson。そこで、 の別のインスタンスを作成PersonNameし、その に値を設定しましたPersonName。その後、エンティティにPersonNameインスタンスを設定しようとしています。Person

そのために、次のようなコードを使用しました。

Class componentClass = Class.forName(clazz.getName());
Field field = parentClass.getDeclaredField(Introspector
                        .decapitalize(clazz.getSimpleName()));
field.setAccessible(true);
field.set(parentClass, componentClass);

ここでparentClassは、PersonインスタンスでcomponentClassあり、PersonNameインスタンスです。に を設定しようとしてPersonNamePersonますが、次の例外が発生します。

java.lang.IllegalArgumentException: Can not set com.rise.common.model.PersonName field
com.rise.common.model.Person.personName to java.lang.Class

では、値を動的に設定するにはどうすればよいでしょうか。

ありがとう。

私のコード全体:

protected void assignProperties(List<Object[]> argResults,
        List<Class> argAllClassesList, Class argParentClass)
        throws ClassNotFoundException, NoSuchFieldException,
        SecurityException, IllegalArgumentException,
        IllegalAccessException, InvocationTargetException, InstantiationException {
    List<Object[]> results = (List<Object[]>) Precondition.ensureNotEmpty(
            argResults, "Output List");
    List<Class<?>> personClassList = new ArrayList<Class<?>>();
    for (Object[] recordValues : results) {
        Class parentClass = Class.forName(this.getPersistentClass()
                .getName());
        parentClass.newInstance();
        int count = 0;
        count = assignValues(recordValues, parentClass, count);
        for (Class clazz : argAllClassesList) {
            Class componentClass = Class.forName(clazz.getName());
            componentClass.newInstance();
            String decapitalize = Introspector.decapitalize(clazz
                    .getSimpleName());
            Field field = parentClass.getDeclaredField(decapitalize);
            field.setAccessible(true);
            assignValues(recordValues, componentClass, count);
             field.set(parentClass, componentClass);
        }
        personClassList.add(parentClass);
    }

    for (Class<?> class1 : personClassList) {
        Class<Person> person = (Class<Person>) class1;
        System.out.println(person);
    }

}

private int assignValues(Object[] argRecordValues, Class argClass,
        int argCount) {
    String paramName = Introspector.decapitalize(argClass.getSimpleName());
    if (Precondition.checkNotEmpty(paramName)) {
        List<Field> fieldNames = TenantConfigHelper.getInstance()
                .getModelNameVsFieldsMap().get(paramName);
        try {
            for (Field field : fieldNames) {
                BeanUtils.setProperty(argClass, field.getName(),
                        argRecordValues[argCount]);
                ++argCount;
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
    return argCount;
}
4

4 に答える 4

3

メッセージは何が問題なのかを説明しています: componentClass はPersonNameのインスタンスではありません。型のオブジェクトですClass(おそらくClass<PersonName>)。クラスのインスタンス化を忘れている可能性があります。

編集:

あなたのコードは:

parentClass.newInstance();

componentClass.newInstance();

これは行うのと同じです

new Parent();

new ParentName();

したがって、インスタンスを作成しますが、それを変数に割り当てないため、作成されたインスタンスで何もしません。これはすぐにガベージコレクション可能になります。

あなたがしたい

Object parent = parentClass.newInstance();
Object component = componentClass.newInstance();
field.set(parent, component);
于 2013-08-01T18:35:20.940 に答える
1

私はこれと同じタイプの答えを探していましたが、基本的に誰もがオブジェクトで指定しているものは正しいです。List<Object>実際のクラス名の代わりに、一般的なリストも作成しました。以下は、オブジェクト型のリストを返す関数です。クラス名を渡し、それを .loadClass でロードします。.newInstance を使用して、その新しいクラス インスタンスで新しいオブジェクトを作成するよりも。dList には、className 変数で渡すクラスである各 objectClass のすべての情報が読み込まれます。残りは基本的に、結果セットの値を使用して、その特定のクラス内のすべての「セット」メソッドを動的に呼び出すだけです。

protected List<Object> FillObject(ResultSet rs, String className)
    {
        List<Object> dList = new ArrayList<Object>();

        try
        {
            ClassLoader classLoader = GenericModel.class.getClassLoader();

            while (rs.next())
            {
                Class reflectionClass = classLoader.loadClass("models." + className);

                Object objectClass = reflectionClass.newInstance();

                Method[] methods = reflectionClass.getMethods();

                for(Method method: methods)
                {
                    if (method.getName().indexOf("set") > -1)
                    {
                        Class[] parameterTypes = method.getParameterTypes();

                        for(Class pT: parameterTypes)
                        {
                            Method setMethod = reflectionClass.getMethod(method.getName(), pT);

                            switch(pT.getName())
                            {
                                case "int":
                                    int intValue = rs.getInt(method.getName().replace("set", ""));
                                    setMethod.invoke(objectClass, intValue);
                                    break;

                                case "java.util.Date":
                                    Date dateValue = rs.getDate(method.getName().replace("set", ""));
                                    setMethod.invoke(objectClass, dateValue);
                                    break;

                                case "boolean":
                                    boolean boolValue = rs.getBoolean(method.getName().replace("set", ""));
                                    setMethod.invoke(objectClass, boolValue);
                                    break;

                                default:
                                    String stringValue = rs.getString(method.getName().replace("set", ""));
                                    setMethod.invoke(objectClass, stringValue);
                                    break;
                            }
                        }
                    }
                }

                dList.add(objectClass);
            }
        }
        catch (Exception e)
        {
            this.setConnectionMessage("ERROR: reflection class loading: " + e.getMessage());
        }

        return dList;
    }
于 2014-01-11T03:45:41.427 に答える