如何打印java对象而不获取“sometype@2f92e0f4"?

vshtjzan  于 2021-07-03  发布在  Java
关注(0)|答案(10)|浏览(296)

我有一个类定义如下:

public class Person {
  private String name;

  // constructor and getter/setter omitted
}

我试图打印我的类的一个示例:

System.out.println(myPerson);

但我得到了以下结果: com.foo.Person@2f92e0f4 .
当我试图打印一组 Person 物体:

Person[] people = //...
System.out.println(people);

我得到了结果: [Lcom.foo.Person;@28a418fc 这个输出意味着什么?如何更改此输出以使其包含我的人名?如何打印我的物品集?
注:这是一个关于这个主题的规范问答。

nfeuvbwi

nfeuvbwi1#

默认情况下,java中的每个对象都有 toString() 输出objecttype@hashcode.
如果你想要更多有意义的完整信息,那么你需要覆盖 toString() 你班上的方法。

public class Person {
  private String name;

  // constructor and getter/setter omitted

  // overridding toString() to print name
  public String toString(){
     return name;  
  }
}

现在,当您使用 System.out.prtinln(personObj); 它将打印人员的姓名,而不是类名和哈希代码。
在第二种情况下,当您试图打印数组时,它会打印 [Lcom.foo.Person;@28a418fc 数组类型及其哈希代码。
如果你想打印人名,有很多方法。
您可以编写自己的函数来迭代每个人并打印

void printPersonArray(Person[] persons){
    for(Person person: persons){
        System.out.println(person);
    }
}

可以使用arrays.tostring()打印它。对我来说这似乎是最简单的。

System.out.println(Arrays.toString(persons));
 System.out.println(Arrays.deepToString(persons));  // for nested arrays

您可以用java8方式打印它(使用流和方法引用)。

Arrays.stream(persons).forEach(System.out::println);

也许还有其他方法。希望这有帮助。:)

s4chpxco

s4chpxco2#

java中的每个类都有 toString() 方法,如果您将该类的某个对象传递给 System.out.println() . 默认情况下,此调用返回classname@hashcode 那个物体的形状。

{
    SomeClass sc = new SomeClass();
    // Class @ followed by hashcode of object in Hexadecimal
    System.out.println(sc);
}

可以重写类的tostring方法以获得不同的输出。看这个例子

class A {
    String s = "I am just a object";
    @Override
    public String toString()
    {
        return s;
    }
}

class B {
    public static void main(String args[])
    {
        A obj = new A();
        System.out.println(obj);
    }
}
hlswsv35

hlswsv353#

在eclipse中,转到类,右键单击->源->生成 toString() ;
它将覆盖 toString() 方法并将打印该类的对象。

mccptt67

mccptt674#

如果你直接打印任何对象的人,它将 ClassName@HashCode 按密码。
对你来说 com.foo.Person@2f92e0f4 正在打印。哪里 Person 是对象所属的类,并且 2f92e0f4 是对象的哈希代码。

public class Person {
  private String name;

  public Person(String name){
  this.name = name;
  }
  // getter/setter omitted

   @override
   public String toString(){
        return name;
   }
}

如果你想用 Person 然后它会打印名字

Class Test
 {
  public static void main(String... args){
    Person obj = new Person("YourName");
    System.out.println(obj.toString());
  }
}
5uzkadbs

5uzkadbs5#

背景

所有java对象都有一个 toString() 方法,该方法在您尝试打印对象时调用。

System.out.println(myObject);  // invokes myObject.toString()

此方法在 Object 类(所有java对象的超类)。这个 Object.toString() 方法返回一个相当难看的字符串,由类名和 @ 十六进制中对象的符号和哈希代码。代码如下所示:

// Code of Object.toString()
public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

结果,例如 com.foo.MyType@2f92e0f4 因此可以解释为: com.foo.MyType -类的名称,即类是 MyType 在包裹里 com.foo . @ -把绳子连在一起 2f92e0f4 对象的哈希代码。
数组类的名称看起来有点不同,这在javadocs中有很好的解释 Class.getName() . 例如, [Ljava.lang.String 指: [ -一维数组(相对于 [[ 或者 [[[ 等等) L -数组包含类或接口 java.lang.String -数组中对象的类型

自定义输出

打电话的时候打印一些不同的东西 System.out.println(myObject) ,必须重写 toString() 方法。下面是一个简单的例子:

public class Person {

  private String name;

  // constructors and other methods omitted

  @Override
  public String toString() {
    return name;
  }
}

现在如果我们打印一张 Person ,我们看到他们的名字而不是 com.foo.Person@12345678 .
记住 toString() 只是将对象转换为字符串的一种方法。通常,这个输出应该以清晰简洁的方式完整地描述您的对象。更好的 toString() 为了我们的 Person 类可能是:

@Override
public String toString() {
  return getClass().getSimpleName() + "[name=" + name + "]";
}

例如。, Person[name=Henry] . 这对于调试/测试来说是非常有用的数据。
如果您只想关注对象的一个方面或包含大量的jazzy格式,那么最好定义一个单独的方法。 String toElegantReport() {...} .

自动生成输出

许多ide都支持自动生成 toString() 方法,基于类中的字段。例如,参见eclipse和intellij的文档。
一些流行的java库也提供了这个特性。一些例子包括: ToStringBuilder 来自apache commons lang MoreObjects.ToStringHelper 来自谷歌Guava @ToString Lombok湖项目注解

打印对象组

所以你创造了一个很好的 toString() 为了你们班。如果将该类放入数组或集合中会发生什么?

数组

如果有对象数组,可以调用 Arrays.toString() 生成数组内容的简单表示。例如,考虑以下数组 Person 物体:

Person[] people = { new Person("Fred"), new Person("Mike") };
System.out.println(Arrays.toString(people));

// Prints: [Fred, Mike]

注意:这是对静态方法的调用 toString() 在arrays类中,这与我们上面讨论的不同。
如果有多维数组,可以使用 Arrays.deepToString() 达到同样的输出。

收藏

大多数集合都会基于调用生成漂亮的输出 .toString() 在每个元素上。

List<Person> people = new ArrayList<>();
people.add(new Person("Alice"));
people.add(new Person("Bob"));    
System.out.println(people);

// Prints [Alice, Bob]

所以你只需要确保你的列表元素定义了一个好的 toString() 如上所述。

s4chpxco

s4chpxco6#

如果您查看对象类(java中所有类的父类),那么tostring()方法的实现是

public String toString() {
       return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

无论何时在java中打印任何对象,都会调用tostring()。现在由您决定是否重写tostring(),然后您的方法将调用其他对象类方法调用。

dsekswqp

dsekswqp7#

在intellij中,可以通过按alt+inset,然后选择tostring()来自动生成tostring方法这里是测试类的输出:

public class test  {
int a;
char b;
String c;
Test2 test2;

@Override
public String toString() {
    return "test{" +
            "a=" + a +
            ", b=" + b +
            ", c='" + c + '\'' +
            ", test2=" + test2 +
            '}';
 }
}

如您所见,它通过连接类的几个属性来生成字符串,对于原语,它将打印它们的值,对于引用类型,它将使用它们的类类型(在本例中是test2的string方法)。

5gfr0r5j

5gfr0r5j8#

我更喜欢使用一个实用函数,它使用gson将java对象反序列化为json字符串。

/**
 * This class provides basic/common functionalities to be applied on Java Objects.
 */
public final class ObjectUtils {

    private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();

    private ObjectUtils() {
         throw new UnsupportedOperationException("Instantiation of this class is not permitted in case you are using reflection.");
    }

    /**
     * This method is responsible for de-serializing the Java Object into Json String.
     *
     * @param object Object to be de-serialized.
     * @return String
     */
    public static String deserializeObjectToString(final Object object) {
        return GSON.toJson(object);
    }
}
gopyfrb3

gopyfrb39#

我认为apache提供了一个更好的util类,它提供了一个获取字符串的函数

ReflectionToStringBuilder.toString(object)
xsuvu9jc

xsuvu9jc10#

我成功地用 Jackson Spring5号。根据对象的不同,jackson可能不会在所有情况下都起作用。

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

ObjectMapper mapper = new ObjectMapper();
Staff staff = createStaff();
// pretty print
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(staff);
System.out.println("-------------------------------------------------------------------")
System.out.println(json);
System.out.println("-------------------------------------------------------------------")

输出类似于

-------------------------------------------------------------------
{
  "id" : 1,
  "internalStaffId" : "1",
  "staffCms" : 1,
  "createdAt" : "1",
  "updatedAt" : "1",
  "staffTypeChange" : null,
  "staffOccupationStatus" : null,
  "staffNote" : null
}
-------------------------------------------------------------------

更多示例使用 Jackson 在这里
你可以试试 GSON 也。应该是这样的:

Gson gson = new Gson();
System.out.println(gson.toJson(objectYouWantToPrint).toString());

相关问题