2017-11-12 3 views
0

저는 리플렉션을 사용하는 것에 상당히 익숙하며 현재 필드를 설정하기 위해 사용자 지정 반사 유틸리티를 구현하려고합니다. springboots ReflectionsTestUtils를 살펴보면 setFields가 어떻게 수행되는지에 대한 이해가 약합니다. 현재 매개 변수로 Object 및 ImmutableMap을 사용하여이를 구현하려고합니다.필드를 설정하기위한 사용자 지정 반영 방법

생각은 해시 맵의 필드/키 값을 개체에있는 필드와 비교하는 것입니다. 나는 전반적인 아이디어를 이해하지만 구현하려고 시도한 메소드는 맵에서 필드를 검색하고 객체의 필드를 비교하는 작업이 아닌 것 같습니다.

내 질문 : 아래 구현을 시도한 것보다이를 달성하는 데 더 효과적인 방법이 있습니까? 내가 여기에 올바른 방법을 향하고 모든 팁 주어 감사하겠습니다 경우

확실하지 :

public static void setField(Object object, ImmutableMap<String, Object> map) 
    throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { 
     if (object instanceof Object) { 
     Field[] fields = object.getClass().getDeclaredFields(); 

     for (Field aField : fields) { 
     for (Map.Entry<String, Object> entry : map.entrySet()) { 
      if (entry.getKey() instanceof Object) { 
      String value = entry.getKey(); 
      checkPrimitiveValue(aField, object, value); 
     } 
     } 
     } 
    } 

}

private static void checkPrimitiveValue(Field field, Object object, String value) throws IllegalArgumentException, IllegalAccessException { 
// Find out Primitive and parse the string to correct value 
if (field.getType() == boolean.class) { 
    field.setAccessible(true); 
    field.set(object, Boolean.parseBoolean(value)); 
} else if (field.getType() == long.class) { 
    field.setAccessible(true); 
    field.set(object, Long.parseLong(value)); 
} else if (field.getType() == int.class) { 
    field.setAccessible(true); 
    field.set(object, Integer.parseInt(value)); 
} else if (field.getType() == double.class) { 
    field.setAccessible(true); 
    field.set(object, Double.parseDouble(value)); 
} else { // String is used 
    field.setAccessible(true); 
    field.set(object, value); 
} 

}

+3

질문은? – IEE1394

답변

1

테스트 :

if (object instanceof Object) 

은 (는) c를 제외하고는 쓸모가 없습니다.

if (object != null) 

당신은 개체의 모든 필드 맵의 모든 키를 할당하고 있습니다 : 오브젝트가 null ASE, 그래서 여기를 작성하는 더 좋은 방법입니다. 난 당신이 뭔가하고 싶었던 것 같아요 : 지금 당신이지도의 값이 문자열 있다고 가정 전달하는 이유를하지 않는

public static void setField(Object object, ImmutableMap<String, Object> map) 
    throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { 
     if (object != null) { 
      Field[] fields = object.getClass().getDeclaredFields(); 

      for (Field aField: fields) { 
       Object value = map.get(aField.getName()); 
       assignValue(aField, object, value); 
      } 
     } 
    } 

을 (정적 유형은 객체이다). 원시적 형의

private static void assignValue(Field field, Object object, Object value) 
    throws IllegalArgumentException, IllegalAccessException, 
      NoSuchFieldException, SecurityException { 
    field.setAccessible(true); 
    if (field.getType().isPrimitive()) 
     if (value == null) { 
      value = defaultValue(field.getType()); 
     } else if (value instanceof String) { 
      value = parseValue(field.getType(), (String)value); 
     } 
    } 
    field.set(object, value); 
} 

기본값 : 기본 유형에 문자열에서

private static Object defaultValue(Class<?> clazz) { 
    if (clazz == boolean.class) { 
     return Boolean.FALSE; 
    } else if (clazz == char.class) { 
     return (char)0; 
    } else if (clazz == byte.class) { 
     return (byte)0; 
    } else if (clazz == short.class) { 
     return (short)0; 
    } else if (clazz == int.class) { 
     return 0; 
    } else if (clazz == long.class) { 
     return 0L; 
    } else if (clazz == float.class) { 
     return 0F; 
    } else if (clazz == double.class) { 
     return 0.0; 
    } else { 
     throw new IllegalArgumentException("Not a primitive type"); 
    } 
} 

변환 (내가하지 않는 당신이 그 일을하는 이유,하지만 여기있다) :

private static Object parseValue(Class<?> type, String s) { 
    if (type == boolean.class) { 
     return Boolean.valueOf(s); 
    } else if (type == char.class) { 
     return (char)Integer.parseInt(s); 
    } else if (type == byte.class) { 
     return Byte.valueOf(s); 
    } else if (type == short.class) { 
     return Short.valueOf(s); 
    } else if (type == int.class) { 
     return Integer.valueOf(s); 
    } else if (type == long.class) { 
     return Long.valueOf(s); 
    } else if (type == float.class) { 
     return Float.valueOf(s); 
    } else if (type == double.class) { 
     return Double.valueOf(s); 
    } else { 
     throw new IllegalArgumentException("Not a primitive type"); 
    } 
} 
관련 문제