“SomeType @ 2f92e0f4” almadan Java nesnesimi nasıl yazdırabilirim?


301

Aşağıdaki gibi tanımlanan bir sınıf var:

public class Person {
  private String name;

  // constructor and getter/setter omitted
}

Sınıfımın bir örneğini yazdırmaya çalıştım:

System.out.println(myPerson);

ama şu çıktıyı aldım: com.foo.Person@2f92e0f4.

Bir Personnesne dizisini yazdırmaya çalıştığımda da benzer bir şey oldu :

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

Çıktı aldım: [Lcom.foo.Person;@28a418fc

Bu çıktı ne anlama geliyor? Bu çıktıyı kişimin adını içerecek şekilde nasıl değiştirebilirim? Ve nesnelerimin koleksiyonlarını nasıl yazdırabilirim?

Not : Bu, bu konu hakkında kanonik bir Soru ve Cevap olarak tasarlanmıştır.


1
Sen kullanabilirsiniz GSON json ve tersi dönüştürme nesnesine kütüphane. Hata ayıklama için çok faydalıdır.
Ashish Rawat

Yanıtlar:


403

Arka fon

Tüm Java nesnelerinin toString(), nesneyi yazdırmaya çalıştığınızda çağrılan bir yöntemi vardır.

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

Bu yöntem Objectsınıfta tanımlanır (tüm Java nesnelerinin üst sınıfı). Object.toString()Yöntemin, sınıf, bir ad oluşan oldukça çirkin görünümlü dize döndürür @sembolü ve karma kodu onaltılık nesnenin. Bunun kodu şuna benzer:

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

Bu nedenle böyle bir sonuç com.foo.MyType@2f92e0f4şöyle açıklanabilir:

  • com.foo.MyType - sınıfın adı, yani sınıf MyTypepakette com.foo.
  • @ - dizeye birlikte katılır
  • 2f92e0f4 nesnenin hashcode'u.

Dizi sınıflarının adı biraz farklı görünür, bu da Javadocs için iyi açıklanmıştır Class.getName(). Örneğin [Ljava.lang.String:

  • [- (zıt olarak, tek boyutlu dizi [[ya da [[[vs.)
  • L - dizi bir sınıf veya arayüz içeriyor
  • java.lang.String - dizideki nesnelerin türü

Çıktıyı Özelleştirme

Aradığınızda farklı bir şey yazdırmak için System.out.println(myObject), size gerekir geçersiztoString() kendi sınıfında yöntemi. İşte basit bir örnek:

public class Person {

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

Şimdi bir a yazdırırsak Person, onların adını görmekteyiz com.foo.Person@12345678.

Bir nesnenin bir dizeye dönüştürülmesinin toString()sadece bir yolu olduğunu unutmayın . Tipik olarak bu çıktı nesnenizi açık ve öz bir şekilde tam olarak tanımlamalıdır. Sınıfımız toString()için daha iyi bir şey Personolabilir:

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

Hangi baskı, örneğin Person[name=Henry]. Hata ayıklama / test etme için gerçekten yararlı bir veri parçası.

Nesnenizin yalnızca bir yönüne odaklanmak veya çok sayıda cazip biçimlendirme eklemek istiyorsanız, bunun yerine ayrı bir yöntem tanımlamak daha iyi olabilir, örn String toElegantReport() {...}.


Çıktıyı Otomatik Oluşturma

Birçok IDEtoString() , sınıftaki alanlara bağlı olarak otomatik yöntem oluşturma desteği sunar . Örneğin Eclipse ve IntelliJ belgelerine bakın .

Birçok popüler Java kütüphanesi de bu özelliği sunar. Bazı örnekler:


Nesne gruplarını yazdırma

Böylece toString()sınıfınız için hoş bir şey yarattınız . Bu sınıf bir diziye veya koleksiyona yerleştirilirse ne olur?

Diziler

Bir dizi nesneniz varsa Arrays.toString(), dizinin içeriğinin basit bir temsilini oluşturmak için arayabilirsiniz . Örneğin, bu Personnesne dizisini göz önünde bulundurun :

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

// Prints: [Fred, Mike]

Not: Bu, yukarıda tartıştığımızdan farklı olan Arrays sınıfında çağrılan statik bir yönteme çağrıdır toString().

Eğer bir varsa çok boyutlu dizi , kullanabileceğiniz Arrays.deepToString()çıktı aynı tür elde etmek.

Koleksiyonları

Çoğu koleksiyon .toString(), her öğeyi çağırmaya dayalı güzel bir çıktı üretecektir .

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

// Prints [Alice, Bob]

Bu yüzden, liste öğelerinizin toString()yukarıda tartışıldığı gibi bir hoş tanımladığından emin olmanız gerekir .


return String.format( getClass().getSimpleName() + "[ name=%s ]", name);ve gerçekten bunun yerine namealıcıyı kullanmalıdır getName()(ancak alıcılar Kişi sınıfında atlanmıştı ...) ama bir alıcı kullanılmışsa ...return String.format( getClass().getSimpleName() + "[ name=%s ]", getName());
CrandellWS

Java dosyasında iki sınıf varsa, o zaman ortak olmayan bir sınıf nesnesi oluşturmak nasıl A.java genel sınıf A {} sınıf B {} ------ C.java genel sınıf C {A a = yeni A ( ); }
yatinbc

Aşırı yüklü sürümleri olduğuna dikkat edin, Arrays.toString()bu yüzden ilkel diziler için de kullanabilirsiniz ( int[], double[]). Ayrıca Arrays.deepToString()çok boyutlu ilkel dizilerini güzelce işler.
Ole VV

1
@ MasterJoe2 Emin değilim, belki de negatif değerleri dizeye kodlamaya çalışırken çirkin görüneceğini düşündüler mi?
Duncan Jones

55

Apache dize almak için bir işlev sağlayan daha iyi bir util sınıfı sağlar düşünüyorum

ReflectionToStringBuilder.toString(object)

5
Bunun avantajı, sınıfın düzenlenmesini gerektirmemesidir; bu bazen mümkün değildir. Ancak, iç içe geçmiş nesneleri de özyinelemeli olarak nasıl yazdırabilirim?
lukas84

35

Java'daki her sınıf, toString()varsayılan olarak, bu sınıfın bazı nesnelerini iletirseniz çağrılan yöntemi kullanır System.out.println(). Varsayılan olarak, bu çağrı bu nesnenin className @ hashcode değerini döndürür.

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

Farklı çıktılar elde etmek için sınıfın toString yöntemini geçersiz kılabilirsiniz. Bu örneğe bakın

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);
    }
}

3
Bu iyi koymak ve kısa bir cevap ama OP oluyor neden açıklığa kavuşturmak için ise [Lcom.foo.Person;@28a418fcçıkış var: çıktı olarak toString()da yöntemin, ama türü için zamanında oluşturulan sınıfta uygulanan birinin Person[]değil Person(bkz stackoverflow.com/a/8546532/1542343 ).
gvlasov

Bu çıktı package.Class@Hashcode anlamına gelir. Varsayılan toString () yöntemi gibi bir dönüş türüne sahiptir. return Object.hasCode () veya sınıf koduyla birlikte onaltılık biçimde hashcode döndüren benzer bir return ifadesi.
Pankaj Manali

14

Eclipse'de, sınıfınıza gidin, sağ tıklayın-> kaynak-> Oluşturun toString();

toString()Yöntemi geçersiz kılar ve o sınıfın nesnesini yazdırır.


10

Java nesnesini JSON dizesine serileştirmek için GSON kullanan bir yardımcı program işlevini kullanmayı tercih ederim .

/**
 * 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);
    }
}

Olmalı return Gson.toJson(object);, aksi takdirde mükemmel çalışır.
Nakrule

Sadece bu.
Agam

5

İntellij'de, alt + inset tuşlarına basıp toString () öğesini seçerek toString yöntemini otomatik olarak oluşturabilirsiniz.

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

Gördüğünüz gibi, sınıfın çeşitli niteliklerini birleştirerek bir String oluşturur, ilkel değerler için değerlerini basar ve referans türleri için sınıf tiplerini kullanır (bu durumda Test2'nin string yöntemine).


4

Varsayılan olarak, Java'daki her Object toString()ObjectType @ HashCode çıktısını veren yönteme sahiptir.

Daha anlamlı bilgiler istiyorsanız toString(), sınıfınızdaki yöntemi geçersiz kılmanız gerekir .

public class Person {
  private String name;

  // constructor and getter/setter omitted

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

Şimdi System.out.prtinln(personObj);bunu kullanarak kişi nesnesini yazdırdığınızda, sınıf adı ve karma kodu yerine kişinin adını yazdırır.

İkinci durumda diziyi yazdırmaya çalıştığınızda [Lcom.foo.Person;@28a418fc, Dizi türünü ve bunun karma kodunu yazdırır .


Kişi adlarını yazdırmak istiyorsanız, birçok yol vardır.

Her bir kişiyi yineleyen ve yazdıran kendi işlevinizi yazabilirsiniz

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

Arrays.toString () kullanarak yazdırabilirsiniz. Bu benim için en basit gibi görünüyor.

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

Java 8 yolunu yazdırabilirsiniz (akışları ve yöntem referansını kullanarak).

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

Başka yollar da olabilir. Bu yardımcı olur umarım. :)


3

Eğer doğrudan herhangi bir nesneyi yazdırırsanız ClassName@HashCode, bu Kod için olacaktır .

sizin durumunuzda com.foo.Person@2f92e0f4yazdırılıyor. Burada Person, nesnenin ait 2f92e0f4olduğu ve Object'in hashCode öğesi olan bir sınıftır .

public class Person {
  private String name;

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

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

Şimdi nesnesini Kullanmaya çalışırsanız Person, adı yazdırır

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

2

Object sınıfına (Java'daki tüm sınıfların üst sınıfı) bakarsanız, toString () yöntemi uygulaması

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

Java'da herhangi bir nesneyi yazdırdığınızda toString () yöntemi çağrılır. ToString () öğesini geçersiz kılarsanız, yönteminiz diğer Object sınıfı yöntem çağrısını çağırır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.