2013-08-14 2 views
1

데이터는 클래스 MyType의 ArrayList입니다. 코드를 사용하면 처리되지 않은 예외를 말하는 컴파일되지 않습니다. 실행할 때 비공개 멤버에 액세스 할 수 없습니다. 그런 다음 MyType의 모든 회원 필드를 공개로 변경합니다. 그런 다음이 코드가 작동합니다. 그러나 확실하게 데이터를 가져 오는 더 좋은 방법이 있어야합니까?알 수없는 클래스에서 데이터를 가져 오는 가장 좋은 방법은 무엇입니까

for (Object object : data)//get one object 
    { 
     ArrayList<Field> fields = 
       new ArrayList<Field>(Arrays.asList(object.getClass().getDeclaredFields()));//get all its fields 
     for(Field field : fields) 
      { 
      try { 
       System.out.println(field.get(object));//print its fields value 
      } catch (IllegalArgumentException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IllegalAccessException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      } 

    } 
+1

성취하려는 것은 무엇입니까? 이상적으로 당신은 a) 클래스를 알 수 있습니다. b) Bean이고 (예를 들어) BeanUtils를 사용합니다. 또는 c) 알려진 인터페이스를 구현 한 다음 인터페이스를 통해 질의합니다. 문맥없이 미가공 물체를보고 있다면, 이것은 얻을 수있는만큼 좋은 것입니다. –

답변

2

개인 필드에 대한 액세스를 허용하려면 Field.setAccessible(true)을 사용하십시오.

try { 
     field.setAccessible(true);  
     System.out.println(field.get(object));//print its fields value 
    } catch (IllegalArgumentException e) { 
     // TODO Auto-generated catch block 
       e.printStackTrace(); 
    } 
1

가장 깨끗한 방법은 인터페이스를 생성하고이를 파생 시키거나 추상 수퍼 클래스에서 파생시키는 것입니다. 두 경우 모두 컴파일러에서 구조를 알 수 있습니다.

Method.class.getDeclaredField(name) 
0

당신은 FieldMethodsetAccessible(boolean)을 사용할 수 있으며, Constructor을 호출자가 일반적으로 액세스 할 수없는 것이 아닌 public 멤버에 액세스하려면 : 다음 코드에 의해 반사와 하나의 필드를 얻을 수 있습니다 에. 이렇게하면 오류가 제거됩니다.

보다 표준화 된 방법은 introspection을 사용하는 것입니다. 클래스가 JavaBean 규칙을 따르는 경우 IntrospectorBeanInfo을 사용하여 PropertyDescriptor 인스턴스를 가져올 수 있습니다.이 인스턴스를 통해 bean의 공용 읽기 및 쓰기 메소드 (getter 및 setters)에 액세스 할 수 있습니다. 여기

public class JavaBean { 

    private boolean valid; 
    private String name; 
    private String label; 

    public boolean isValid() { 
     return valid; 
    } 

    public String getName() { 
     return name; 
    } 

    public String getLabel() { 
     return label; 
    } 

    public void setValid(boolean valid) { 
     this.valid = valid; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public void setLabel(String label) { 
     this.label = label; 
    } 
} 

, 우리는 valid, namelabel 속성을 선언 : 예를 들어, 다음 예제 콩입니다. 필드 이름은 속성 이름을 결정하는 데 사용되지 않습니다. 대신, get/isset 방법이 사용됩니다. 또한 원시 boolean 속성은 getter 접두어로 is을 사용합니다.

그런 다음 사용하는 성찰 :

Object unknownType = new JavaBean(); 
BeanInfo javaBeanInfo = Introspector.getBeanInfo(JavaBean.class); 
for (PropertyDescriptor property : javaBeanInfo.getPropertyDescriptors()) { 
    System.out.println(property.getName()); 
} 

이 (반드시 순서대로) 인쇄됩니다 : 모든 클래스에 존재하는 getClass() 방법을, 그래서 class이기 때문에

class 
valid 
name 
label 

class 여기에 재산으로 간주됩니다. 그런 다음 다음 얻고 일반적인 반사 API를 사용하여 지정된 개체의 속성 값을 설정하는 그들에 Method.invoke을 사용하여, 각각 getter와 setter를있는 Method 객체를 얻을 수 PropertyDescriptor.readMethodPropertyDescriptor.writeMethod을 사용할 수 있습니다

. PropertyDescriptor에는 속성 유형 및 속성 이름과 같은 다른 정보도 있습니다. 이는 리플렉션을 직접 사용하는 대신 사용할 수 있습니다. 또한 Introspector에 의해 반환 된 BeanInfo을 다른 사용자가 재정의하여 맞춤 구현할 수 있습니다.

관련 문제