Java에서 클래스 속성을 반복하는 방법은 무엇입니까?
Java의 클래스 속성을 동적으로 반복하는 방법은 무엇입니까?
예 :
public class MyClass{
private type1 att1;
private type2 att2;
...
public void function(){
for(var in MyClass.Attributes){
System.out.println(var.class);
}
}
}
이것이 자바에서 가능합니까?
당신이 원하는 것을하기위한 언어 적 지원은 없습니다.
리플렉션을 사용하여 런타임에 유형의 멤버에 반사적으로 액세스 할 수 있습니다 (예 : Class.getDeclaredFields()
의 배열을 가져 오기 위해 with Field
).하지만 수행하려는 작업에 따라 이것이 최상의 솔루션이 아닐 수 있습니다.
또한보십시오
관련 질문
- 성찰이란 무엇이며 왜 유용합니까?
- Java Reflection : 왜 그렇게 나쁜가요?
- 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 2nd Edition, 항목 53 : 리플렉션보다 인터페이스 선호
다음은 책에서 발췌 한 것입니다.
주어진
Class
객체, 당신은 얻을 수 있습니다Constructor
,Method
그리고Field
클래스의 생성자, 메소드와 필드를 나타내는 경우. [그들은] 당신이 그들의 기본 대응 물을 반사적으로 조작 할 수 있도록합니다 . 그러나이 힘에는 대가가 따릅니다.
- 컴파일 타임 검사의 모든 이점을 잃게됩니다.
- 반사 액세스를 수행하는 데 필요한 코드는 서투르고 장황합니다.
- 성능이 저하됩니다.
일반적으로 런타임시 일반 응용 프로그램에서 객체에 반사적으로 액세스해서는 안됩니다.
There are a few sophisticated applications that require reflection. Examples include [...omitted on purpose...] If you have any doubts as to whether your application falls into one of these categories, it probably doesn't.
Accessing the fields directly is not really good style in java. I would suggest creating getter and setter methods for the fields of your bean and then using then Introspector and BeanInfo classes from the java.beans package.
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);
}
While I agree with Jörn's answer if your class conforms to the JavaBeabs spec, here is a good alternative if it doesn't and you use Spring.
Spring has a class named ReflectionUtils that offers some very powerful functionality, including doWithFields(class, callback), a visitor-style method that lets you iterate over a classes fields using a callback object like this:
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));
});
}
But here's a warning: the class is labeled as "for internal use only", which is a pity if you ask me
Simple way to iterate over class fields and obtain values from object:
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 has Reflection (java.reflection.*), but I would suggest looking into a library like Apache Beanutils, it will make the process much less hairy than using reflection directly.
Here is a solution which sorts the properties alphabetically and prints them all together with their values:
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
'Program Tip' 카테고리의 다른 글
Mac OS X에서 대용량 파일 편집 (0) | 2020.10.18 |
---|---|
.NET 위임 유형에 대한 적절한 명명 규칙? (0) | 2020.10.18 |
Seaborn Facet Plot에 제목을 추가하는 방법 (0) | 2020.10.18 |
프로그래밍 방식으로 Android에서 뒤로 버튼을 누르는 방법은 무엇입니까? (0) | 2020.10.18 |
파일이없는 폴더 및 하위 폴더 목록을 얻으려면 어떻게합니까? (0) | 2020.10.18 |