2013-04-29 1 views
2

지정된 (int) 값을 정의하는 인터페이스에서 필드를 반환하는 메서드를 구현하고 싶습니다. 인터페이스에 대한 소스가 없습니다.프로그래밍 방식으로 Java 인터페이스를 읽는 방법?

그래서, 서명이 같은 수 :

public ArrayList<String> getFieldnames(Object src, int targetValue); 

내가 내부적으로 선언 된 필드를 찾아 목록을 반환 값에 대해 각을 테스트 할 수 있으리라 믿고있어.

불행하게도이 구현은 잘못된 것입니다. 인터페이스 자체와 함께 호출 할 때 필드가 전혀없는 것과 같습니다. 인터페이스를 구현하는 객체를 전달하면 가능한 필드 목록이 너무 넓어서 사용할 수 없게됩니다.

도움 주셔서 감사합니다.

+0

전체 대답은 아래를 참조하십시오. 서명에'Class src'를 사용하고, 호출 사이트를 변경하여'MyInterface.class'를 전달합니다. 이렇게하면 내부 getClass()를 피하고 매력처럼 작동합니다! – user1944491

답변

2
public ArrayList<String> getFieldnames(Object src, int targetValue) { 
    final Class<?> myInterfaceClass = MyInterface.class; 
    ArrayList<String> fieldNames = new ArrayList<>(); 
    if (src != null) { 
    for (Class<?> currentClass = src.getClass(); currentClass != null; currentClass = currentClass.getSuperclass()) { 
     Class<?> [] interfaces = currentClass.getInterfaces(); 
     if (Arrays.asList(interfaces).contains(myInterfaceClass)) { 
     for (Field field : currentClass.getDeclaredFields()) { 
      if (field.getType().equals(int.class)) { 
      try { 
       int value = field.getInt(null); 
       if (value == targetValue) { 
       fieldNames.add(field.getName()); 
       } 
      } catch (IllegalAccessException ex) { 
       // Do nothing. Always comment empty blocks. 
      } 
      } 
     } 
     } 
    } 
    } 
    return fieldNames; 
} 
+0

이것이 내 자신과 가장 가깝기 때문에 이것을 대답으로 받아들이면'Class 'typespec을 생각 나게합니다! 감사! – user1944491

0

src.getClass() 

반환 SRC 클래스는 인터페이스 없습니다. 차라리 객체에 통과 한 것이지만이

interface I { 
} 

class A implements I { 
} 

new A().getClass() -- returns A.class 
+0

정확히! 인터페이스를 전달하는 방법을 알아 내서 파싱 할 수 있습니다. 'getFieldNames (I, aField)'를 호출 할 수 없습니다.'getFieldNames (new I() {a, aField)'를 호출 할 수 없습니다. (마지막 하나는 컴파일되지만) 어떻게 인터페이스 객체를 메소드에 전달합니까? – user1944491

+0

개체 클래스 -> src.getClass(). getInterfaces()에서 모든 인터페이스를 가져 오거나 단순히 인터페이스를 MyInterface.class로 전달하십시오. –

0

을 고려, 나는 문자열 값에 서명을 변경하고 FQIN 전달하는 것은 단지뿐만 아니라 일을 있다고 가정 해 보겠습니다.

아이디어 덕분에 (그리고 Google에서 나를 안내 해준) 덕분에 < this question에게 감사드립니다.

솔루션 :

public ArrayList<String> getFieldnamesByValue(Class<?>x, int targetValue) 
{ 
    ArrayList<String> s = new ArrayList<String>(); 

    if(x != null) 
    { 
     Field[] flist = x.getDeclaredFields(); 
     for (Field f : flist) 
      if(f.getType() == int.class) 
       try { 
        if(f.getInt(null) == targetValue) { 
         s.add(f.getName()); 
         break; 
        } 
       } catch (IllegalArgumentException e) { 
       } catch (IllegalAccessException e) { 
       } 
    } 
    return s; 
} 
+0

정규화 된 이름을 사용할 필요가 없습니다. 서명에서'String interfaceFQName'을 제거하고, 첫 번째'try/catch'를 제거하고,'Class x = MyInterface.class; '로 대체하십시오. –

+0

이것이 바로 Alvin입니다. 나는이 메소드의 시그니처를'getFieldnames (Class src, int targetValue)'로 바꿨다. 그래서 몸체는 그냥 루프 안으로 곧바로 들어갈 수있다. 호출하는 사이트에서,'ArrayList names = getFieldNames (SOBConstants.class, 45)'와 voila에서 신속하게 못 박을 수 있습니다! – user1944491

관련 문제