我有一个人,看起来像这样的信息类:
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 + ...
所有变量。 我试图使用反射从所示实现它这个问题 ,但我不能管理打印实例变量。
什么是解决这个问题的正确方法是什么?
Answer 1:
从实现的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();
}
Answer 2:
你为什么要重塑时有开源那些已经做的工作相当漂亮的车轮。
无论阿帕奇共LANGS和弹簧支持一些非常灵活的生成器模式
对于Apache,这里是你如何做到这一点反思
@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 ,甚至用自己的风格进行定制。
我没有亲自尝试春天ToStringCreator API,但它看起来非常相似。
Answer 3:
如果您使用的是Eclipse,这应该是很容易:
1.Press Alt + Shift的+ S
2.Choose “生成的toString()......”
请享用! 你可以拥有的toString()S的任何模板。
这也适用于的getter / setter方法。
Answer 4:
通用的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);
}
Answer 5:
当访问该字段值,通过实例,而不是空。
为什么不能在这里使用的代码生成? Eclipse中,例如,会为你生成一个reasoble的toString实现。
Answer 6:
另一个简单的办法是让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
生成getter和setter你, 这里是全功能列表。
Answer 7:
如果从输出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;
}
Answer 8:
除了与@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;
}
Answer 9:
我会得到我的回答如下:
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);
}
}
}
文章来源: Printing all variables value from a class