Bagaimana cara mencetak objek Java saya tanpa mendapatkan "SomeType @ 2f92e0f4"?

Mar 19 2015

Saya memiliki kelas yang ditentukan sebagai berikut:

public class Person {
  private String name;

  // constructor and getter/setter omitted
}

Saya mencoba mencetak contoh kelas saya:

System.out.println(myPerson);

tapi aku punya output sebagai berikut: com.foo.Person@2f92e0f4.

Hal serupa terjadi ketika saya mencoba mencetak larik Personobjek:

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

Saya mendapatkan hasilnya: [Lcom.foo.Person;@28a418fc

Apa artinya keluaran ini? Bagaimana cara mengubah keluaran ini sehingga berisi nama orang saya? Dan bagaimana cara mencetak koleksi objek saya?

Catatan : ini dimaksudkan sebagai Q&A kanonik tentang subjek ini.

Jawaban

422 DuncanJones Mar 19 2015 at 15:59

Latar Belakang

Semua objek Java memiliki toString()metode yang dipanggil saat Anda mencoba dan mencetak objek.

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

Metode ini didefinisikan di Objectkelas (superclass dari semua objek Java). The Object.toString()method mengembalikan string mencari cukup jelek, terdiri dari nama kelas, sebuah @simbol dan kode hash dari objek dalam heksadesimal. Kode untuk ini terlihat seperti:

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

Hasil seperti com.foo.MyType@2f92e0f4itu dapat dijelaskan sebagai:

  • com.foo.MyType - nama kelas, yaitu kelas yang ada MyTypedi dalam paket com.foo.
  • @ - menggabungkan string bersama
  • 2f92e0f4 kode hash objek.

Nama kelas array terlihat sedikit berbeda, yang dijelaskan dengan baik di Javadocs for Class.getName(). Misalnya, [Ljava.lang.Stringartinya:

  • [- array satu dimensi (sebagai lawan [[atau [[[dll.)
  • L - array berisi kelas atau antarmuka
  • java.lang.String - jenis objek dalam larik

Menyesuaikan Output

Untuk mencetak sesuatu yang berbeda ketika Anda menelepon System.out.println(myObject), Anda harus menimpa para toString()metode di kelas Anda sendiri. Berikut contoh sederhananya:

public class Person {

  private String name;
  
  // constructors and other methods omitted
  
  @Override
  public String toString() {
    return name;
  }
}

Sekarang jika kita mencetak a Person, kita melihat nama mereka daripada com.foo.Person@12345678.

Ingatlah bahwa toString()ini hanyalah salah satu cara untuk mengubah objek menjadi string. Biasanya, keluaran ini harus mendeskripsikan objek Anda secara jelas dan ringkas. Yang lebih baik toString()untuk Personkelas kami mungkin:

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

Yang akan dicetak, misalnya Person[name=Henry]. Itu adalah bagian data yang sangat berguna untuk debugging / pengujian.

Jika Anda ingin fokus hanya pada satu aspek dari objek Anda atau menyertakan banyak format jazzy, Anda mungkin lebih baik untuk mendefinisikan metode terpisah, mis String toElegantReport() {...}.


Menghasilkan Output secara otomatis

Banyak IDE menawarkan dukungan untuk membuat toString()metode secara otomatis, berdasarkan kolom di kelas. Lihat dokumen untuk Eclipse dan IntelliJ , misalnya.

Beberapa perpustakaan Java populer juga menawarkan fitur ini. Beberapa contoh termasuk:


Mencetak kelompok objek

Jadi, Anda telah membuat yang bagus toString()untuk kelas Anda. Apa yang terjadi jika kelas tersebut ditempatkan ke dalam array atau koleksi?

Array

Jika Anda memiliki larik objek, Anda dapat memanggil Arrays.toString()untuk menghasilkan representasi sederhana dari konten larik. Misalnya, pertimbangkan larik Personobjek ini:

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

// Prints: [Fred, Mike]

Catatan: ini adalah panggilan ke metode statis yang disebut toString()dalam kelas Array, yang berbeda dengan yang telah kita bahas di atas.

Jika Anda memiliki larik multi-dimensi , Anda dapat menggunakan Arrays.deepToString()untuk mendapatkan jenis keluaran yang sama.

Koleksi

Sebagian besar koleksi akan menghasilkan keluaran yang cantik berdasarkan pemanggilan .toString()setiap elemen.

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

// Prints [Alice, Bob]

Jadi Anda hanya perlu memastikan elemen daftar Anda mendefinisikan bagus toString()seperti yang dibahas di atas.

61 RohithK Apr 15 2015 at 20:31

Saya pikir apache menyediakan kelas util yang lebih baik yang menyediakan fungsi untuk mendapatkan string

ReflectionToStringBuilder.toString(object)
37 PankajManali Mar 19 2015 at 17:04

Setiap kelas di Java memiliki toString()metode di dalamnya secara default, yang dipanggil jika Anda meneruskan beberapa objek dari kelas itu ke System.out.println(). Secara default, panggilan ini mengembalikan kode hash className @ objek itu.

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

Anda dapat mengganti metode toString kelas untuk mendapatkan keluaran yang berbeda. Lihat contoh ini

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);
    }
}
16 ketankk Apr 21 2016 at 20:45

Di Eclipse, Pergi ke kelas Anda, Klik kanan-> source-> Generate toString();

Ini akan mengganti toString()metode dan akan mencetak objek dari kelas itu.

12 Agam Oct 09 2018 at 19:18

Saya lebih suka menggunakan fungsi utilitas yang menggunakan GSON untuk membatalkan serialisasi objek Java menjadi string 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);
    }
}
6 Mr.Q Jul 28 2016 at 13:00

Dalam intellij Anda dapat menghasilkan metode toString secara otomatis dengan menekan alt + inset dan kemudian memilih toString () di sini adalah keluaran untuk kelas pengujian:

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 +
            '}';
 }
}

Seperti yang Anda lihat, itu menghasilkan String dengan menggabungkan, beberapa atribut kelas, untuk primitif itu akan mencetak nilainya dan untuk jenis referensi itu akan menggunakan jenis kelas mereka (dalam hal ini metode string Test2).

6 adn.911 Dec 02 2017 at 23:23

Secara default, setiap Objek di Java memiliki toString()metode yang menghasilkan ObjectType @ HashCode.

Jika Anda menginginkan informasi yang lebih bermakna maka Anda perlu mengganti toString()metode di kelas Anda.

public class Person {
  private String name;

  // constructor and getter/setter omitted

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

Sekarang ketika Anda mencetak objek orang menggunakannya System.out.prtinln(personObj);akan mencetak nama orang itu bukan nama kelas dan kode hash.

Dalam kasus kedua Anda ketika Anda mencoba untuk mencetak array, itu mencetak [Lcom.foo.Person;@28a418fctipe Array dan itu kode hash.


Jika ingin mencetak nama orang, ada banyak cara.

Anda dapat menulis fungsi Anda sendiri yang mengulang setiap orang dan mencetaknya

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

Anda bisa mencetaknya menggunakan Arrays.toString (). Ini tampaknya yang paling sederhana bagi saya.

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

Anda bisa mencetaknya dengan java 8 (menggunakan aliran dan referensi metode).

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

Mungkin ada cara lain juga. Semoga ini membantu. :)

4 VikrantKashyap May 06 2016 at 18:22

Jika Anda langsung mencetak objek apa pun dari Orang, itu akan ClassName@HashCodeke Kode.

dalam kasus Anda com.foo.Person@2f92e0f4akan dicetak. Di mana Personkelas di mana objek dimiliki dan 2f92e0f4merupakan kode hash dari Objek.

public class Person {
  private String name;

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

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

Sekarang jika Anda mencoba menggunakan objek Personmaka itu akan mencetak nama

Class Test
 {
  public static void main(String... args){
    Person obj = new Person("YourName");
    System.out.println(obj.toString());
  }
}
3 YasirShabbirChoudhary Mar 27 2017 at 13:21

Jika Anda melihat kelas Object (kelas Induk dari semua kelas di Java) implementasi metode toString () adalah

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

setiap kali Anda mencetak objek apa pun di Java maka toString () akan dipanggil. Sekarang terserah Anda jika Anda mengganti toString () maka metode Anda akan memanggil metode panggilan kelas Object lainnya.

user9869932 Nov 06 2020 at 00:34

Saya berhasil menyelesaikan ini menggunakan Jacksondi Spring 5. Bergantung pada objek Jackson mungkin tidak berfungsi di semua kasus.

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("-------------------------------------------------------------------")

hasilnya akan seperti ini

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

Lebih banyak contoh digunakan Jackson di sini

Anda GSONjuga bisa mencoba . Seharusnya seperti ini:

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