클래스에서 모든 변수 값 인쇄
다음과 같은 Person에 대한 정보가있는 클래스가 있습니다.
public class Contact {
private String name;
private String location;
private String address;
private String email;
private String phone;
private String fax;
public String toString() {
// Something here
}
// Getters and setters.
}
모든 변수에 대해 toString()
반환 하고 싶습니다 this.name +" - "+ this.locations + ...
. 이 질문 에서 볼 수 있듯이 리플렉션을 사용하여 구현하려고 했지만 인스턴스 변수를 인쇄 할 수 없습니다.
이 문제를 해결하는 올바른 방법은 무엇입니까?
에서 구현 toString :
public String toString() {
StringBuilder result = new StringBuilder();
String newLine = System.getProperty("line.separator");
result.append( this.getClass().getName() );
result.append( " Object {" );
result.append(newLine);
//determine fields declared in this class only (no fields of superclass)
Field[] fields = this.getClass().getDeclaredFields();
//print field names paired with their values
for ( Field field : fields ) {
result.append(" ");
try {
result.append( field.getName() );
result.append(": ");
//requires access to private field:
result.append( field.get(this) );
} catch ( IllegalAccessException ex ) {
System.out.println(ex);
}
result.append(newLine);
}
result.append("}");
return result.toString();
}
이미 일을 꽤 잘하고있는 오픈 소스가 있는데 왜 바퀴를 재발 명하고 싶습니까?
Apache common-langs 와 spring 모두 매우 유연한 빌더 패턴을 지원합니다.
아파치의 경우 반사적으로 수행하는 방법은 다음과 같습니다.
@Override
public String toString()
{
return ToStringBuilder.reflectionToString(this);
}
관심있는 필드 만 인쇄하려는 경우 수행하는 방법은 다음과 같습니다.
@Override
public String toString()
{
return new ToStringBuilder(this)
.append("name", name)
.append("location", location)
.append("address", address)
.toString();
}
기본이 아닌 ToStringStyle을 사용하여 인쇄 출력을 "스타일링" 하거나 자신 만의 스타일로 사용자 정의 할 수 있습니다.
개인적으로 Spring ToStringCreator API를 사용 해본 것은 아니지만 매우 비슷해 보입니다.
Eclipse를 사용하는 경우 이것은 쉽습니다.
1. Alt+ Shift+를 누릅니다.S
2. "Generate toString () ..."을 선택합니다.
즐겨! toString ()의 모든 템플릿을 가질 수 있습니다.
이것은 getter / setter에서도 작동합니다.
리플렉션 및 스타일 사용자 지정을 사용하는 일반 toString () 한 줄 :
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
...
public String toString()
{
return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
필드 값에 액세스 할 때 널 대신 인스턴스를 전달하십시오.
여기서 코드 생성을 사용하지 않는 이유는 무엇입니까? 예를 들어 Eclipse는 합리적인 toString 구현을 생성합니다.
또 다른 간단한 방법은 방법을 Lombok
생성하는 toString
것입니다.
이를 위해 :
Lombok
프로젝트에 추가 하기 만하면 됩니다.@ToString
클래스 정의에 주석 추가- 클래스 / 프로젝트를 컴파일하면 완료됩니다.
예를 들어 귀하의 경우 클래스는 다음과 같습니다.
@ToString
public class Contact {
private String name;
private String location;
private String address;
private String email;
private String phone;
private String fax;
// Getters and setters.
}
이 경우 출력 예 :
Contact(name=John, location=USA, address=SF, email=foo@bar.com, phone=99999, fax=88888)
주석 사용 방법에@ToString
대한 자세한 내용 .
주의 : 게터와 세터 를 Lombok
생성 할 수도 있습니다. 여기 에 전체 기능 목록이 있습니다.
의 출력을 ReflectionToStringBuilder.toString()
충분히 읽을 수없는 경우 다음과 같은 코드가 있습니다.
1) 필드 이름을 알파벳순으로 정렬
2) 행 시작 부분에 별표가있는 널이 아닌 필드에 플래그 지정
public static Collection<Field> getAllFields(Class<?> type) {
TreeSet<Field> fields = new TreeSet<Field>(
new Comparator<Field>() {
@Override
public int compare(Field o1, Field o2) {
int res = o1.getName().compareTo(o2.getName());
if (0 != res) {
return res;
}
res = o1.getDeclaringClass().getSimpleName().compareTo(o2.getDeclaringClass().getSimpleName());
if (0 != res) {
return res;
}
res = o1.getDeclaringClass().getName().compareTo(o2.getDeclaringClass().getName());
return res;
}
});
for (Class<?> c = type; c != null; c = c.getSuperclass()) {
fields.addAll(Arrays.asList(c.getDeclaredFields()));
}
return fields;
}
public static void printAllFields(Object obj) {
for (Field field : getAllFields(obj.getClass())) {
field.setAccessible(true);
String name = field.getName();
Object value = null;
try {
value = field.get(obj);
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
System.out.printf("%s %s.%s = %s;\n", value==null?" ":"*", field.getDeclaringClass().getSimpleName(), name, value);
}
}
테스트 하네스 :
public static void main(String[] args) {
A a = new A();
a.x = 1;
B b = new B();
b.x=10;
b.y=20;
System.out.println("=======");
printAllFields(a);
System.out.println("=======");
printAllFields(b);
System.out.println("=======");
}
class A {
int x;
String z = "z";
Integer b;
}
class B extends A {
int y;
private double z = 12345.6;
public int a = 55;
}
@cletus 답변 추가, 모든 모델 필드 (상위 계층)를 가져와 field.setAccessible(true)
개인 멤버에 액세스하도록 설정 해야합니다. 다음은 전체 스 니펫입니다.
@Override
public String toString() {
StringBuilder result = new StringBuilder();
String newLine = System.getProperty("line.separator");
result.append(getClass().getSimpleName());
result.append( " {" );
result.append(newLine);
List<Field> fields = getAllModelFields(getClass());
for (Field field : fields) {
result.append(" ");
try {
result.append(field.getName());
result.append(": ");
field.setAccessible(true);
result.append(field.get(this));
} catch ( IllegalAccessException ex ) {
// System.err.println(ex);
}
result.append(newLine);
}
result.append("}");
result.append(newLine);
return result.toString();
}
private List<Field> getAllModelFields(Class aClass) {
List<Field> fields = new ArrayList<>();
do {
Collections.addAll(fields, aClass.getDeclaredFields());
aClass = aClass.getSuperclass();
} while (aClass != null);
return fields;
}
나는 다음과 같이 내 대답을 얻을 것이다.
import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class findclass {
public static void main(String[] args) throws Exception, IllegalAccessException {
new findclass().findclass(new Object(), "objectName");
new findclass().findclass(1213, "int");
new findclass().findclass("ssdfs", "String");
}
public Map<String, String>map=new HashMap<String, String>();
public void findclass(Object c,String name) throws IllegalArgumentException, IllegalAccessException {
if(map.containsKey(c.getClass().getName() + "@" + Integer.toHexString(c.hashCode()))){
System.out.println(c.getClass().getSimpleName()+" "+name+" = "+map.get(c.getClass().getName() + "@" + Integer.toHexString(c.hashCode()))+" = "+c);
return;}
map.put(c.getClass().getName() + "@" + Integer.toHexString(c.hashCode()), name);
Class te=c.getClass();
if(te.equals(Integer.class)||te.equals(Double.class)||te.equals(Float.class)||te.equals(Boolean.class)||te.equals(Byte.class)||te.equals(Long.class)||te.equals(String.class)||te.equals(Character.class)){
System.out.println(c.getClass().getSimpleName()+" "+name+" = "+c);
return;
}
if(te.isArray()){
if(te==int[].class||te==char[].class||te==double[].class||te==float[].class||te==byte[].class||te==long[].class||te==boolean[].class){
boolean dotflag=true;
for (int i = 0; i < Array.getLength(c); i++) {
System.out.println(Array.get(c, i).getClass().getSimpleName()+" "+name+"["+i+"] = "+Array.get(c, i));
}
return;
}
Object[]arr=(Object[])c;
for (Object object : arr) {
if(object==null)
System.out.println(c.getClass().getSimpleName()+" "+name+" = null");
else {
findclass(object, name+"."+object.getClass().getSimpleName());
}
}
}
Field[] fields=c.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
if(field.get(c)==null){
System.out.println(field.getType().getSimpleName()+" "+name+"."+field.getName()+" = null");
continue;
}
findclass(field.get(c),name+"."+field.getName());
}
if(te.getSuperclass()==Number.class||te.getSuperclass()==Object.class||te.getSuperclass()==null)
return;
Field[]faFields=c.getClass().getSuperclass().getDeclaredFields();
for (Field field : faFields) {
field.setAccessible(true);
if(field.get(c)==null){
System.out.println(field.getType().getSimpleName()+" "+name+"<"+c.getClass().getSuperclass().getSimpleName()+"."+field.getName()+" = null");
continue;
}
Object check=field.get(c);
findclass(field.get(c),name+"<"+c.getClass().getSuperclass().getSimpleName()+"."+field.getName());
}
}
public void findclass(Object c,String name,Writer writer) throws IllegalArgumentException, IllegalAccessException, IOException {
if(map.containsKey(c.getClass().getName() + "@" + Integer.toHexString(c.hashCode()))){
writer.append(c.getClass().getSimpleName()+" "+name+" = "+map.get(c.getClass().getName() + "@" + Integer.toHexString(c.hashCode()))+" = "+c+"\n");
return;}
map.put(c.getClass().getName() + "@" + Integer.toHexString(c.hashCode()), name);
Class te=c.getClass();
if(te.equals(Integer.class)||te.equals(Double.class)||te.equals(Float.class)||te.equals(Boolean.class)||te.equals(Byte.class)||te.equals(Long.class)||te.equals(String.class)||te.equals(Character.class)){
writer.append(c.getClass().getSimpleName()+" "+name+" = "+c+"\n");
return;
}
if(te.isArray()){
if(te==int[].class||te==char[].class||te==double[].class||te==float[].class||te==byte[].class||te==long[].class||te==boolean[].class){
boolean dotflag=true;
for (int i = 0; i < Array.getLength(c); i++) {
writer.append(Array.get(c, i).getClass().getSimpleName()+" "+name+"["+i+"] = "+Array.get(c, i)+"\n");
}
return;
}
Object[]arr=(Object[])c;
for (Object object : arr) {
if(object==null){
writer.append(c.getClass().getSimpleName()+" "+name+" = null"+"\n");
}else {
findclass(object, name+"."+object.getClass().getSimpleName(),writer);
}
}
}
Field[] fields=c.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
if(field.get(c)==null){
writer.append(field.getType().getSimpleName()+" "+name+"."+field.getName()+" = null"+"\n");
continue;
}
findclass(field.get(c),name+"."+field.getName(),writer);
}
if(te.getSuperclass()==Number.class||te.getSuperclass()==Object.class||te.getSuperclass()==null)
return;
Field[]faFields=c.getClass().getSuperclass().getDeclaredFields();
for (Field field : faFields) {
field.setAccessible(true);
if(field.get(c)==null){
writer.append(field.getType().getSimpleName()+" "+name+"<"+c.getClass().getSuperclass().getSimpleName()+"."+field.getName()+" = null"+"\n");
continue;
}
Object check=field.get(c);
findclass(field.get(c),name+"<"+c.getClass().getSuperclass().getSimpleName()+"."+field.getName(),writer);
}
}
}
참고 URL : https://stackoverflow.com/questions/1526826/printing-all-variables-value-from-a-class
'Program Tip' 카테고리의 다른 글
NSData를 Swift에서 [Uint8]로 (0) | 2020.11.22 |
---|---|
HTML 페이지를 AJAX를 통해 검색된 내용으로 교체 (0) | 2020.11.22 |
목록 요소에서 \ n을 제거하는 방법은 무엇입니까? (0) | 2020.11.22 |
WPF에서 현재 마우스 화면 좌표를 어떻게 얻습니까? (0) | 2020.11.22 |
제출 후 유효성 검사 오류가 발생하면 p : dialog를 열어 둡니다. (0) | 2020.11.22 |