Hoe druk ik mijn Java-object af zonder “Sunchype @ 2F92E0F4”?

Ik heb een klasse gedefinieerd als volgt:

public class Person {
  private String name;
  // constructor and getter/setter omitted
}

Ik heb geprobeerd een exemplaar van mijn klas af te drukken:

System.out.println(myPerson);

Maar ik heb de volgende uitvoer: com.foo.Person@2f92e0f4.

Er is een soortgelijk iets gebeurd toen ik probeerde een reeks Personobjecten af ​​te drukken:

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

Ik heb de uitvoer: [Lcom.foo.Person;@28a418fc

Wat betekent deze output? Hoe verander ik deze uitvoer, zodat het de naam van mijn persoon bevat? En hoe druk ik collecties van mijn objecten af?

Opmerking : Dit is bedoeld als een Canonical Q & AMP; A over dit onderwerp.


Antwoord 1, Autoriteit 100%

Achtergrond

Alle Java-objecten hebben een toString()-methode, die wordt aangeroepen wanneer u het object probeert af te drukken.

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

Deze methode is gedefinieerd in het Objectklasse (de superklasse van alle Java-objecten). De Object.toString()methode retourneert een vrij lelijk uitziende string, samengesteld uit de naam van de klasse, een @symbool en het hashcodevan het object in hexadecimaal. De code hiervoor ziet er als volgt uit:

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

Een resultaat zoals com.foo.MyType@2f92e0f4kan daarom worden uitgelegd als:

  • com.foo.MyType– de naam van de klasse, dwz de klasse is MyTypein het pakket com.foo.
  • @– voegt de string samen
  • 2f92e0f4de hashcode van het object.

De naam van arrayklassen ziet er een beetje anders uit, wat goed wordt uitgelegd in de Javadocs voor Class.getName(). [Ljava.lang.Stringbetekent bijvoorbeeld:

  • [– een eendimensionale array (in tegenstelling tot [[of [[[enz.)
  • L– de array bevat een klasse of interface
  • java.lang.String– het type objecten in de array

De uitvoer aanpassen

Om iets anders af te drukken wanneer u System.out.println(myObject)belt, moet u overschrijven De toString()METHODE IN UW KLASSE. Hier is een eenvoudig voorbeeld:

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

Nu, als we een Personafdrukken, zien we hun naam in plaats van com.foo.Person@12345678.

Houd er rekening mee dat toString()Just One WANKELIJK VOOR EEN OBJECT WORDT DAT EEN OBJECT WORDT OM TE WERELD NAAR EEN STRING. Meestal moet deze uitgang uw object volledig en beknopte manier volledig beschrijven. Een betere toString()Voor onze PersonKlasse kan zijn:

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

die zouden afdrukken, b.v. Person[name=Henry]. Dat is een echt nuttig stuk gegevens voor foutopsporing / testen.

Als u zich op slechts één aspect van uw object wilt concentreren of veel jazzy-formattering wilt opnemen, is u misschien beter om in plaats daarvan een afzonderlijke methode te definiëren, b.v. String toElegantReport() {...}.


het automatisch genereren van de uitvoer

Veel ID’s bieden ondersteuning voor het automatisch genereren van een toString()Methode, gebaseerd op de velden in de klas. Zie documenten voor Eclipse en intellerij , bijvoorbeeld.

Verschillende populaire Java-bibliotheken bieden deze functie ook aan. Enkele voorbeelden zijn:


Groepen voorwerpen afdrukken

Dus heb je een leuke toString()voor je klas gemaakt. Wat gebeurt er als die klasse in een array of een verzameling wordt geplaatst?

Arrays

Als je een array met objecten hebt, kun je Arrays.toString()om een eenvoudige weergave van de inhoud van de array te maken. Overweeg bijvoorbeeld deze reeks Person-objecten:

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

Opmerking: dit is een aanroep van een statischemethode genaamd toString()in de klasse Arrays, wat anders is dan wat we hierboven hebben besproken.

p>

Als je een multidimensionale arrayhebt, kun je Arrays.deepToString()om hetzelfde soort uitvoer te verkrijgen.

Collecties

De meeste collecties zullen een mooie output produceren op basis van het aanroepen van .toString()op elk element.

List<Person> people = new ArrayList<>();
people.add(new Person("Alice"));
people.add(new Person("Bob"));    
System.out.println(people);
// Prints [Alice, Bob]

Je hoeft er dus alleen voor te zorgen dat je lijstelementen een mooie toString()definiëren, zoals hierboven besproken.


Antwoord 2, autoriteit 16%

Ik denk dat apache een betere util-klasse biedt die een functie biedt om de string op te halen

ReflectionToStringBuilder.toString(object)

Antwoord 3, autoriteit 8%

Elke klasse in Java heeft standaard de methode toString(), die wordt aangeroepen als je een object van die klasse doorgeeft aan System.out.println(). Standaard retourneert deze aanroep de className@hashcode van dat object.

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

Je kunt de methode toString van een klasse overschrijven om een andere uitvoer te krijgen. Zie dit voorbeeld

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

Antwoord 4, autoriteit 3%

In Eclipse,
Ga naar je klas,
Klik met de rechtermuisknop->source->Genereer toString();

Het zal de methode toString()overschrijven en het object van die klasse afdrukken.


Antwoord 5, autoriteit 3%

Ik gebruik liever een hulpprogramma-functie die GSONgebruikt om het Java-object te deserialiseren in JSON-tekenreeks .

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

Antwoord 6

In intellij kun je automatisch de toString-methode genereren door op alt+inset te drukken en vervolgens toString() te selecteren. Hier is een uitvoer voor een testklasse:

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

Zoals je kunt zien, genereert het een String door verschillende attributen van de klasse samen te voegen, voor primitieven zal het hun waarden afdrukken en voor referentietypes zal het hun klassetype gebruiken (in dit geval de stringmethode van Test2).


Antwoord 7

Standaard heeft elk object in Java de methode toString()die de ObjectType@HashCode uitvoert.

Als je meer betekenisvolle informatie wilt, moet je de toString()methode in je klas overschrijven.

public class Person {
  private String name;
  // constructor and getter/setter omitted
  // overridding toString() to print name
  public String toString(){
     return name;  
  }
}

Als u nu het persoonsobject afdrukt met System.out.prtinln(personObj);, wordt de naam van de persoon afgedrukt in plaats van de klassenaam en hashcode.

In het tweede geval, wanneer u de array probeert af te drukken, drukt het [Lcom.foo.Person;@28a418fchet arraytype en de hashcode af.


Als u de namen van personen wilt afdrukken, zijn er veel manieren.

Je zou je eigen functie kunnen schrijven die elke persoon herhaalt en afdrukt

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

Je zou het kunnen afdrukken met Arrays.toString(). Dit lijkt mij het eenvoudigst.

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

Je zou het op de Java 8-manier kunnen afdrukken (met behulp van streams en methode-referentie).

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

Er kunnen ook andere manieren zijn. Ik hoop dat dit helpt. 🙂


Antwoord 8

Als u een object van een persoon rechtstreeks afdrukt, wordt de ClassName@HashCodenaar de code toegevoegd.

in jouw geval wordt com.foo.Person@2f92e0f4afgedrukt . Waar Personeen klasse is waartoe het object behoort en 2f92e0f4de hashCode van het object is.

public class Person {
  private String name;
  public Person(String name){
  this.name = name;
  }
  // getter/setter omitted
   @override
   public String toString(){
        return name;
   }
}

Als u nu het object van Personprobeert te gebruiken, wordt de naam afgedrukt

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

Antwoord 9

Als je kijkt naar de klasse Object (Ouderklasse van alle klassen in Java), is de implementatie van de methode toString()

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

wanneer u een object in Java afdrukt, wordt toString() aangeroepen. Nu is het aan jou of je toString() overschrijft, dan zal je methode een andere aanroep van de klasse Object aanroepen.


Antwoord 10

Voor een “diepe” toString()is er een alternatief voor de op JSON gebaseerde antwoorden (Jackson, GSON, etc.): ReflectionToStringBuildervan de Apache Commons Lang 3bibliotheek, met RecursiveToStringStyleof MultilineRecursiveToStringStyle. Codevoorbeeld:

System.out.println("My object: " +
    ReflectionToStringBuilder.toString(theObject, new RecursiveToStringStyle()));

Uitvoervoorbeelden:

// RecursiveToStringStyle
Person@7f54[name=Stephen,age=29,smoker=false,job=Job@43cd2[title=Manager]]
// MultilineRecursiveToStringStyle
Person@7f54[
  name=Stephen,
  age=29,
  smoker=false,
  job=Job@43cd2[
    title=Manager
  ]
]

Antwoord 11

Ik heb dit voor elkaar gekregen met Jacksonin het voorjaar van 5. Afhankelijk van het object werkt Jackson mogelijk niet in alle gevallen.

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(json);

de uitvoer zou zoiets zijn als

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

Meer voorbeelden met Jacksonhier

Je kunt GSONook proberen. Het zou zoiets zijn als

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

Other episodes