Java에서 Class Atribute를 루프오버하려면 어떻게 해야 합니까?
Java에서 클래스 속성을 동적으로 루프하려면 어떻게 해야 합니까?
예:
public class MyClass{
private type1 att1;
private type2 att2;
...
public void function(){
for(var in MyClass.Attributes){
System.out.println(var.class);
}
}
}
자바에서도 가능합니까?
당신이 원하는 것을 할 수 있는 언어적 지원은 없습니다.
리플렉션(의 배열을 취득하기 위한 등)을 사용하여 런타임에 타입의 멤버에 리플렉션으로 액세스 할 수 있습니다.다만, 무엇을 하려고 하는가에 따라서는, 이것이 최적인 솔루션이 아닌 경우가 있습니다.
「 」를 참조해 주세요.
- Java 튜토리얼: Reflection API/Advanced Language 토픽: Reflection
관련 질문
예
여기 성찰이 무엇을 할 수 있는지를 보여주는 간단한 예가 있습니다.
import java.lang.reflect.*;
public class DumpFields {
public static void main(String[] args) {
inspect(String.class);
}
static <T> void inspect(Class<T> klazz) {
Field[] fields = klazz.getDeclaredFields();
System.out.printf("%d fields:%n", fields.length);
for (Field field : fields) {
System.out.printf("%s %s %s%n",
Modifier.toString(field.getModifiers()),
field.getType().getSimpleName(),
field.getName()
);
}
}
}
위의 스니펫은 반사를 사용하여 선언된 모든 필드를 검사합니다.class String
; 다음과 같은 출력이 생성됩니다.
7 fields:
private final char[] value
private final int offset
private final int count
private int hash
private static final long serialVersionUID
private static final ObjectStreamField[] serialPersistentFields
public static final Comparator CASE_INSENSITIVE_ORDER
유효한 Java 제2판, 항목 53: 반영보다 인터페이스를 선호합니다.
다음은 이 책에서 발췌한 내용입니다.
개체를 지정하면 클래스의 생성자, 메서드 및 필드를 나타내는 , 및 인스턴스를 얻을 수 있습니다.[그것들]은(는) 당신이 그들의 근본적인 상대들을 반사적으로 조종할 수 있게 됩니다.그러나 이 힘에는 다음과 같은 대가가 따릅니다.
- 컴파일 타임 체크의 이점을 모두 잃게 됩니다.
- 리플렉티브 액세스를 실행하기 위해 필요한 코드는 어설프고 상세합니다.
- 퍼포먼스가 저하되다
일반적으로 실행 시 일반 응용 프로그램에서 개체에 반사적으로 액세스하지 않아야 합니다.
성찰이 필요한 몇 가지 정교한 애플리케이션이 있습니다.예를 들어 [...의도적으로 생략...]어플리케이션이 이 카테고리 중 하나에 해당하는지 의심스럽다면 아마 해당 카테고리는 아닐 것입니다.
필드에 직접 액세스하는 것은 Java에서 그다지 좋은 스타일이 아닙니다.bean 필드의 getter 및 setter 메서드를 작성한 후 java.beans 패키지의 Introspector 및 BeanInfo 클래스를 사용하는 것이 좋습니다.
MyBean bean = new MyBean();
BeanInfo beanInfo = Introspector.getBeanInfo(MyBean.class);
for (PropertyDescriptor propertyDesc : beanInfo.getPropertyDescriptors()) {
String propertyName = propertyDesc.getName();
Object value = propertyDesc.getReadMethod().invoke(bean);
}
당신의 클래스가 JavaBeabs 사양에 준거하고 있다면 Jörn의 답변에 동의하지만, 만약 그렇지 않고 Spring을 사용한다면 여기 좋은 대안이 있습니다.
Spring에는 다음과 같은 콜백개체를 사용하여 클래스 필드에서 반복할 수 있는 방문자 스타일의 메서드 doWithFields(class, callback) 등 매우 강력한 기능을 제공하는 ReflectionUtils라는 이름의 클래스가 있습니다.
public void analyze(Object obj){
ReflectionUtils.doWithFields(obj.getClass(), field -> {
System.out.println("Field name: " + field.getName());
field.setAccessible(true);
System.out.println("Field value: "+ field.get(obj));
});
}
하지만 경고 하나 하죠. 이 클래스는 "내부 사용 전용"으로 표시되어 있습니다.이렇게 묻는다면 유감입니다.
클래스 필드에 대해 반복하고 개체에서 값을 가져오는 간단한 방법:
Class<?> c = obj.getClass();
Field[] fields = c.getDeclaredFields();
Map<String, Object> temp = new HashMap<String, Object>();
for( Field field : fields ){
try {
temp.put(field.getName().toString(), field.get(obj));
} catch (IllegalArgumentException e1) {
} catch (IllegalAccessException e1) {
}
}
Java에는 Reflection(java.reflection)이 있습니다.*) 단, Apache Beanutils와 같은 라이브러리를 들여다보는 것이 좋습니다.이것에 의해, 직접 리플렉션을 사용하는 것보다 프로세스가 훨씬 덜 복잡해집니다.
다음은 속성을 알파벳 순으로 정렬하고 해당 값과 함께 인쇄하는 솔루션입니다.
public void logProperties() throws IllegalArgumentException, IllegalAccessException {
Class<?> aClass = this.getClass();
Field[] declaredFields = aClass.getDeclaredFields();
Map<String, String> logEntries = new HashMap<>();
for (Field field : declaredFields) {
field.setAccessible(true);
Object[] arguments = new Object[]{
field.getName(),
field.getType().getSimpleName(),
String.valueOf(field.get(this))
};
String template = "- Property: {0} (Type: {1}, Value: {2})";
String logMessage = System.getProperty("line.separator")
+ MessageFormat.format(template, arguments);
logEntries.put(field.getName(), logMessage);
}
SortedSet<String> sortedLog = new TreeSet<>(logEntries.keySet());
StringBuilder sb = new StringBuilder("Class properties:");
Iterator<String> it = sortedLog.iterator();
while (it.hasNext()) {
String key = it.next();
sb.append(logEntries.get(key));
}
System.out.println(sb.toString());
}
언급URL : https://stackoverflow.com/questions/3333974/how-to-loop-over-a-class-attributes-in-java
'source' 카테고리의 다른 글
MySQL에서 --secure-file-priv를 해결하려면 어떻게 해야 합니까? (0) | 2022.09.04 |
---|---|
주석 누락으로 인해 실행 시 ClassNotFoundException이 발생하지 않는 이유는 무엇입니까? (0) | 2022.09.04 |
악시오스 요격기의 Vue-Router (0) | 2022.09.04 |
LOAD DATA INFILE을 사용하여 MySQL 테이블로 가져올 때 CSV 파일의 열을 건너뛰는 방법은 무엇입니까? (0) | 2022.09.04 |
Axios ajax, Ajax 요청 시 로드 표시 (0) | 2022.09.03 |