[java] 리플렉션 일반 Get 필드 값

리플렉션을 통해 필드 값을 받으려고합니다. 문제는 필드 유형을 모르고 값을 얻는 동안 결정해야한다는 것입니다.

이 코드는이 예외와 함께 발생합니다.

java.lang.String 필드 com …. fieldName을 java.lang.String으로 설정할 수 없습니다.

Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);

Class<?> targetType = field.getType();
Object objectValue = targetType.newInstance();

Object value = field.get(objectValue);

캐스팅을 시도했지만 컴파일 오류가 발생합니다.

field.get((targetType)objectValue)

또는

targetType objectValue = targetType.newInstance();

어떻게해야합니까?



답변

이전에 대답 한 것처럼 다음을 사용해야합니다.

Object value = field.get(objectInstance);

때로는 선호되는 또 다른 방법은 게터를 동적으로 호출하는 것입니다. 예제 코드 :

public static Object runGetter(Field field, BaseValidationObject o)
{
    // MZ: Find the correct method
    for (Method method : o.getMethods())
    {
        if ((method.getName().startsWith("get")) && (method.getName().length() == (field.getName().length() + 3)))
        {
            if (method.getName().toLowerCase().endsWith(field.getName().toLowerCase()))
            {
                // MZ: Method found, run it
                try
                {
                    return method.invoke(o);
                }
                catch (IllegalAccessException e)
                {
                    Logger.fatal("Could not determine method: " + method.getName());
                }
                catch (InvocationTargetException e)
                {
                    Logger.fatal("Could not determine method: " + method.getName());
                }

            }
        }
    }


    return null;
}

또한 클래스가 다른 클래스에서 상속 될 때 필드를 재귀 적으로 결정해야합니다. 예를 들어, 주어진 클래스의 모든 필드를 가져 오는 것;

    for (Class<?> c = someClass; c != null; c = c.getSuperclass())
    {
        Field[] fields = c.getDeclaredFields();
        for (Field classField : fields)
        {
            result.add(classField);
        }
    }


답변

필드의 메소드 를 얻으려면 객체 를 전달해야 하므로

  Field field = object.getClass().getDeclaredField(fieldName);
  field.setAccessible(true);
  Object value = field.get(object);


답변

기본 설정 클래스의 toString () 구현에서 리플렉션을 사용하여 클래스 멤버 및 값을 확인합니다 (간단하고 빠른 디버깅).

내가 사용하는 단순화 된 코드 :

@Override
public String toString() {
    StringBuilder sb = new StringBuilder();

    Class<?> thisClass = null;
    try {
        thisClass = Class.forName(this.getClass().getName());

        Field[] aClassFields = thisClass.getDeclaredFields();
        sb.append(this.getClass().getSimpleName() + " [ ");
        for(Field f : aClassFields){
            String fName = f.getName();
            sb.append("(" + f.getType() + ") " + fName + " = " + f.get(this) + ", ");
        }
        sb.append("]");
    } catch (Exception e) {
        e.printStackTrace();
    }

    return sb.toString();
}

나는 또한 검색했기 때문에 그것이 누군가를 도울 수 있기를 바랍니다.


답변

달성하려는 것이 분명하지는 않지만 코드에서 명백한 오류를 발견했습니다
Field.get(). 필드를 포함하는 객체가 해당 필드의 (가능한) 값이 아닌 인수로 예상됩니다. 그래서 당신은해야 field.get(object)합니다.

필드 값을 찾는 것처럼 보이므로 다음과 같이 얻을 수 있습니다.

Object objectValue = field.get(object);

필드 유형을 인스턴스화 할 필요가없고 빈 / 기본 값을 만들 필요가 없습니다. 또는 내가 놓친 것이있을 수 있습니다.


답변

 Integer typeValue = 0;
 try {
     Class<Types> types = Types.class;
     java.lang.reflect.Field field = types.getDeclaredField("Type");
     field.setAccessible(true);
     Object value = field.get(types);
     typeValue = (Integer) value;
 } catch (Exception e) {
     e.printStackTrace();
 }


답변

잘못된 인수로 get을 호출하고 있습니다.

그것은해야한다:

Object value = field.get(object);


답변

Kotlin에 솔루션을 게시했지만 Java 객체에서도 작동 할 수 있습니다. 모든 객체가이 함수를 사용할 수 있도록 함수 확장을 만듭니다.

fun Any.iterateOverComponents() {

val fields = this.javaClass.declaredFields

fields.forEachIndexed { i, field ->

    fields[i].isAccessible = true
    // get value of the fields
    val value = fields[i].get(this)

    // print result
    Log.w("Msg", "Value of Field "
            + fields[i].name
            + " is " + value)
}}

이 웹 페이지를 살펴보십시오 : https://www.geeksforgeeks.org/field-get-method-in-java-with-examples/