2016-10-04 3 views
0

리플렉션을 사용하여 값을 읽은 약 200 개의 필드가있는 클래스가 제공되었습니다. 내가 반성의 지점입니다 가정으로이 분야의 이러한 다루기 힘든 시간 동안 아주 잘 작동이리플렉션을 사용하지 않고 필드 값을 가져 오는 방법

for (Field f : this.getClass().getFields()) 
     { 
      try 
      { 
       Object o = f.get(this); 

       if (f.getType() == String.class) 
       { 
        //do things with the string 
       } 
      } 
      catch (Exception ex) 
      { 
       logger.error("Cannot get value for field. {}", ex.getMessage()); 
      } 

     } 

처럼 기본적으로 보인다. 나는 그것이 느리기 때문에 그것을 리펙토링하도록 요청 받았다 (그것인가?).

경건한 코딩에 대한 경이로움을 생각해 볼 수있는 유일한 방법은 지금까지 또 다른 빠른 방법입니까?

+1

OP에 작동 코드가있어 리팩터를 요청하기 때문에이 질문을 주제와 관련이없는 것으로 닫으려고합니다. [ask]를보고 [codereview.se]에서이 질문을하는 것을 고려해보십시오. – xenteros

+0

더 나은, 전체 클래스를 넣어. "느리게"- 수업 사용 및 내용에 따라 다릅니다. 개인적으로, 나는 여기 반영이 최상의 해결책이라고 생각한다 ... 만약 당신이 같은 논리를 저장하고 싶다면. 이것은 추상화 실패 (하나의 클래스 안에있는 200 개의 필드가 엉망으로 처리되고! 여러 번 필터링되어야 함)가 아닌 심각한 구현 결함 인 것처럼 보입니다. – Les

+0

느린가요? 너는 말해. 프로파일 러를 프로그램에 추가하고이 루프에서 소요되는 시간을 확인하십시오. –

답변

4

먼저 프로파일 러를 사용하여 실제로 속도가 느린 지 확인해야합니다. 리플렉션은 일반적으로 변수에 액세스하는 것보다 느리지 만 속도가 느려지는 것을 의미하지는 않습니다.

설정자를 사용하여 값을 수정했다면 설정자가 호출 될 때마다 Map<String,Object>을 업데이트하도록 클래스를 리팩터링 할 수 있습니다. 이렇게하면 리플렉션보다 필드에 더 빨리 액세스 할 수 있지만 사용 사례에 따라 가능하지 않을 수도 있습니다.

+0

아, 아주 좋아. 슬프게도 필드는 공개되어 직접 설정됩니다. – Nanor

+1

@Nanor 한 번 세터가 사용됩니다 ...! – Kayaman

3

대부분의 시간은 Field 개체를 가져 오는 데 사용됩니다 (필터링 할 수도 있음). 실제 조회는 꽤 빠를 수 있습니다. ClassValue를 사용하여이 정보를 캐시하고 속도를 높입니다. 내가 하드 코딩 자신의 불신 심의 양을 가지고 올 수

public enum StringFields { 
    INSTANCE; 

    final ClassValue<List<Field>> fieldsCache = new ClassValue<List<Field>>() { 
     @Override 
     protected List<Field> computeValue(Class<?> type) { 
      return Collections.unmodifiableList(
        Stream.of(type.getFields()) 
          .filter(f -> f.getType() == String.class) 
          .peek(f -> f.setAccessible(true)) // turn off security check 
          .collect(Collectors.toList())); 
     } 
    }; 

    public static List<Field> getAllStringFields(Class<?> type) { 
     return INSTANCE.fieldsCache.get(type); 
    } 
} 
+0

그래서 필드의 이름을 알면'Object.get (String)'을 할 수 있고 더 빠를까요? – Nanor

+0

@Nanor Field 객체를 캐시하면 더 빠를 것입니다. 예를 추가하지만 바쁘다. –

1

지금까지 유일한 방법, 또 다른 빠른 방법은 무엇입니까?

당신은 그 필드의 게터를 얻고 그 게터를 판독 코드를 생성하는 반사를 사용할 수 있습니다.

코드 생성은 빌드 단계의 일부가 될 수 있습니다.

관련 문제