2

次の方法でクラスフィールドを反復処理したい

授業がある

public class Parent{

String name;
String lastName;

}

public class Child extends Parent{

int childNumber;
}

親クラスで「get」メソッドが必要です

子供が受け継ぐということ

このメソッドは、フィールドの値をその名前で返します

フィールドの値を取得するにはどうすればよいですか?

メソッドを次のようにしたい:

public Object get(String key){
            Field field;
        Object result = null;
        try {
            field = this.getClass().getDeclaredField(key);
            if(field!=null) {
                field.setAccessible(true);
            }
            result = field.get(this); // this is where my problem, i don't know how to retrieve the field's value
        } catch (NoSuchFieldException | SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

スタックトレース

java.lang.IllegalArgumentException: Can not set int field com.database.User.userID to java.lang.String
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
    at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(Unknown Source)
    at sun.reflect.UnsafeIntegerFieldAccessorImpl.getInt(Unknown Source)
    at sun.reflect.UnsafeIntegerFieldAccessorImpl.get(Unknown Source)
    at java.lang.reflect.Field.get(Unknown Source)
    at com.database.DatabaseObject.get(DatabaseObject.java:106)
    at com.database.DatabaseObject.set(DatabaseObject.java:128)
    at com.database.DatabaseObject.getInsertPreparedStatement(DatabaseObject.java:64)
    at com.database.Database.insert(Database.java:95)
    at com.lenabru.webservice.ElectronicArenaWebService.register(ElectronicArenaWebService.java:21)
    at com.database.Main.main(Main.java:29)
4

3 に答える 3

1

次の 2 つのいずれかを行うことをお勧めします。

  1. 実際のコードに、ここに示す例のようにフィールドが少ない場合は、getXxx()フィールドごとにメソッドを追加してください。たとえば、Parentshould have getName()(これはgetFirstName()?)getLastName()メソッドとChildshould havegetChildNumber()です。

  2. コードがこれよりも複雑な場合は、 を使用し、に委譲しておよびメソッドMapを実装します。get()set()Map

リフレクションは、非常に低いレベルでオブジェクトを操作する必要がある複雑なツールを構築するプログラマーを対象としています。多くの場合、私たちの残りの人にとってより良い解決策があります.

于 2013-08-17T19:57:42.223 に答える
1

このスタック トレースを取得するにはfield.get、 ではなくに文字列値を渡す必要がありますthis。完全な再構築を行い、再度テストします。

UnsafeFieldAccessorImplフィールドが宣言されているクラスから割り当て可能なオブジェクトではなく、文字列を渡そうとすると、指定された紛らわしいエラーメッセージしか表示されないことがわかるように、クラスからの関連メソッドは次のとおりです。

protected void ensureObj(Object o) {
    // NOTE: will throw NullPointerException, as specified, if o is null
    if (!field.getDeclaringClass().isAssignableFrom(o.getClass())) {
        throwSetIllegalArgumentException(o);
    }
}

protected void throwSetIllegalArgumentException(Object o) {
    throwSetIllegalArgumentException(o != null ? o.getClass().getName() : "", "");
}

protected void throwSetIllegalArgumentException(String attemptedType,
                                                String attemptedValue) {
    throw new IllegalArgumentException(getSetMessage(attemptedType,attemptedValue));
}

protected String getSetMessage(String attemptedType, String attemptedValue) {
    String err = "Can not set";
    if (Modifier.isStatic(field.getModifiers()))
        err += " static";
    if (isFinal)
        err += " final";
    err += " " + field.getType().getName() + " field " + getQualifiedFieldName() + " to ";
    if (attemptedValue.length() > 0) {
        err += "(" + attemptedType + ")" + attemptedValue;
    } else {
        if (attemptedType.length() > 0)
            err += attemptedType;
        else
            err += "null value";
    }
    return err;
}
于 2013-08-17T19:18:38.020 に答える
0

Bean フィールドにアクセスしたい場合に使用する最も簡単な方法は、おそらく次のとおりBeanUtilsです。commons-beanutils

System.out.println(BeanUtils.getProperty(child, "name")); // get value from property

BeanUtils.setProperty(c, "lastName", "Ivan Ivanov"); // set value to property
于 2013-08-17T19:27:34.617 に答える