如何在 Java 中正确地覆盖 toString() ?

听起来有点愚蠢,但我需要我的 toString()方法的帮助,这是非常恼人的。 我尝试在网上查找,因为 toString是一个在那里它是搞砸了和“没有找到基德构造函数 # 2”,即使它是在那里,我甚至会做别的事情,它不工作。 好了,这是很多,所以这里是我的代码:

import java.util.*;
class Kid {
String name;
double height;
GregorianCalendar bDay;


public Kid () {
this.name = "HEAD";
this.height = 1;
this.bDay = new GregorianCalendar(1111,1,1);
}


public Kid (String n, double h, String date) {
// method that toString() can't find somehow
StringTokenizer st = new StringTokenizer(date, "/", true);
n = this.name;
h = this.height;
}


public String toString() {
return Kid(this.name, this.height, this.bDay);
}
} //end class

好的,那么上面的 toString (我知道,我的第三个参数是 off,应该是一个 String)是 off。如果我硬编码的第三件事情的值,它会失控,说它不能找到这(上面)。那我怎么才能找到约会对象,然后分手呢?

下面是调用此方法的类

class Driver {
public static void main (String[] args) {
Kid kid1 = new Kid("Lexie", 2.6, "11/5/2009");
System.out.println(kid1.toString());
} //end main method
} //end class

我试着研究多个构造函数,但是没有用。 我尝试研究 toString()方法,并尝试使用以前我创建的 toString()方法逻辑,但这是全新的,所以它从来没有工作。

帮忙?

329359 次浏览

The toString is supposed to return a String.

public String toString() {
return "Name: '" + this.name + "', Height: '" + this.height + "', Birthday: '" + this.bDay + "'";
}

I suggest you make use of your IDE's features to generate the toString method. Don't hand-code it.

For instance, Eclipse can do so if you simply right-click on the source code and select Source > Generate toString

You can creating new object in the toString(). use

return "Name = " + this.name +" height= " + this.height;

instead of

return Kid(this.name, this.height, this.bDay);

You may change the return string as required. There are other ways to store date instead calander.

You can't call a constructor as if it was a normal method, you can only call it with new to create a new object:

Kid newKid = new Kid(this.name, this.height, this.bDay);

But constructing a new object from your toString() method is not what you want to be doing.

Following code is a sample. Question based on the same, instead of using IDE based conversion, is there a faster way to implement so that in future the changes occur, we do not need to modify the values over and over again?

@Override
public String toString() {
return "ContractDTO{" +
"contractId='" + contractId + '\'' +
", contractTemplateId='" + contractTemplateId + '\'' +
'}';
}

Java toString() method

If you want to represent any object as a string, toString() method comes into existence.

The toString() method returns the string representation of the object.

If you print any object, java compiler internally invokes the toString() method on the object. So overriding the toString() method, returns the desired output, it can be the state of an object etc. depends on your implementation.

Advantage of Java toString() method

By overriding the toString() method of the Object class, we can return values of the object, so we don't need to write much code.

Output without toString() method

class Student{
int id;
String name;
String address;


Student(int id, String name, String address){
this.id=id;
this.name=name;
this.address=address;
}


public static void main(String args[]){
Student s1=new Student(100,”Joe”,”success”);
Student s2=new Student(50,”Jeff”,”fail”);


System.out.println(s1);//compiler writes here s1.toString()
System.out.println(s2);//compiler writes here s2.toString()
}
}


Output:Student@2kaa9dc
Student@4bbc148

You can see in the above example #1. printing s1 and s2 prints the Hashcode values of the objects but I want to print the values of these objects. Since java compiler internally calls toString() method, overriding this method will return the specified values. Let's understand it with the example given below:

Example#2


Output with overriding toString() method


class Student{
int id;
String name;
String address;


Student(int id, String name, String address){
this.id=id;
this.name=name;
this.address=address;
}


//overriding the toString() method
public String toString(){
return id+" "+name+" "+address;
}
public static void main(String args[]){
Student s1=new Student(100,”Joe”,”success”);
Student s2=new Student(50,”Jeff”,”fail”);


System.out.println(s1);//compiler writes here s1.toString()
System.out.println(s2);//compiler writes here s2.toString()
}
}


Output:100 Joe success
50 Jeff fail

Note that toString() mostly is related to the concept of polymorphism in Java. In, Eclipse, try to click on toString() and right click on it.Then, click on Open Declaration and see where the Superclass toString() comes from.

Well actually you will need to return something like this because toString has to return a string

public String toString() {
return "Name :" + this.name + "whatever :" + this.whatever + "";
}

and you actually do something wrong in the constructer you set the variable the user set to the name while you need to do the opposite. What you shouldn't do

n = this.name

What you should do

this.name = n

Hopes this helps thanks

we can even write like this by creating a new String object in the class and assigning it what ever we want in constructor and return that in toString method which is overridden

public class Student{
int id;
String name;
String address;
String details;
Student(int id, String name, String address){
this.id=id;
this.name=name;
this.address=address;
this.details=id+"  "+name+"  "+address;
}


//overriding the toString() method
public String toString(){
return details;
}
public static void main(String args[]){
Student s1=new Student(100,"Joe","success");
Student s2=new Student(50,"Jeff","fail");


System.out.println(s1);//compiler writes here s1.toString()
System.out.println(s2);//compiler writes here s2.toString()
}
}

If you're interested in Unit-Tests, then you can declare a public "ToStringTemplate", and then you can unit test your toString. Even if you don't unit-test it, I think its "cleaner" and uses String.format.

public class Kid {


public static final String ToStringTemplate = "KidName='%1s', Height='%2s', GregCalendar='%3s'";


private String kidName;
private double height;
private GregorianCalendar gregCalendar;


public String getKidName() {
return kidName;
}


public void setKidName(String kidName) {
this.kidName = kidName;
}


public double getHeight() {
return height;
}


public void setHeight(double height) {
this.height = height;
}


public GregorianCalendar getGregCalendar() {
return gregCalendar;
}


public void setGregCalendar(GregorianCalendar gregCalendar) {
this.gregCalendar = gregCalendar;
}


public String toString() {
return String.format(ToStringTemplate, this.getKidName(), this.getHeight(), this.getGregCalendar());
}
}

Now you can unit test by create the Kid, setting the properties, and doing your own string.format on the ToStringTemplate and comparing.

making ToStringTemplate static-final means "ONE VERSION" of the truth, rather than having a "copy" of the template in the unit-test.

As others explained, the toString is not the place to be instantiating your class. Instead, the toString method is intended to build a string representing the value of an instance of your class, reporting on at least the most important fields of data stored in that object. In most cases, toString is used for debugging and logging, not for your business logic (except some historical methods, like Integer.toString()).

To generate text representing the value of an object for display to a user, add another method. People often name the method something like getDisplayName. For example, DayOfWeek::getDisplayName and Month::getDisplayName.

StringJoiner

As of Java 8 and later, the most modern way to implement toString would use the StringJoiner class. As the doc says:

StringJoiner is used to construct a sequence of characters separated by a delimiter and optionally starting with a supplied prefix and ending with a supplied suffix.

Use like this:

@Override
public String toString ()
{
return new StringJoiner(                           // In Java 8 and later, StringJoiner is used to construct a sequence of characters separated by a delimiter and optionally starting with a supplied prefix and ending with a supplied suffix.
" | " ,                                // Delimiter
Person.class.getSimpleName() + "[ " ,  // Prefix
" ]"                                   // Suffix
)
.add( "name=" + name )                     // Append
.add( "phone=" + phone )                   // Append
.toString();                               // Convert entire sequence to a single `String` object.
}

Person[ name=Alice | phone=555.867.5309 ]

record

Java 16 brings a new way to briefly define a class where the main purpose is to communicate data transparently and immutably: record.

You define a record by merely listing the type and name of each member field. The compiler implicitly creates the constructor, getters, equals & hashCode, and toString.

Default implementation of toString

The default implementation of toString includes each and every member field.

public Kid ( String name , double height , LocalDate birthDate ) {}

Instantiate like any other object.

Kid alice = new Kid( "Alice" , 6.1d , LocalDate.of( 2019 , Month.April , 23 ) ) ;
String output = alice.toString() ;

You may choose to override the default implementation with your own. Overrides are usually not needed given the purpose of a record as a simple data-carrier.

The best way in my opinion is using google gson library:

        @Override
public String toString() {
return new GsonBuilder().setPrettyPrinting().create().toJson(this);
}

or apache commons lang reflection way

  1. if you are use using notepad: then

    public String toString(){
    
    
    return ""; ---now here you can use variables which you have created for your class
    
    
    }
    
  2. if you are using eclipse IDE then press

    -alt +shift +s
    

    -click on override toString method here you will get options to select what type of variables you want to select.

Nice and concise way is to use Lombok annotations. It has @ToString annotation, which will generate an implementation of the toString() method. By default, it will print your class name, along with each field, in order, separated by commas. You can easily customize your output by passing parameters to annotation, e.g.:

@ToString(of = {"name", "lastName"})

Which is equivalent of pure Java:

public String toString() {
return "Person(name=" + this.name + ", lastName=" + this.experienceInYears + ")";
}

If you're just using toString() for debugging a DTO, you can generate human readable output automatically with something like the following:

import com.fasterxml.jackson.databind.ObjectMapper;
...
public String toString() {
try { return new ObjectMapper().writeValueAsString(this); }
catch (Exception e) { return "{ObjectMapper failed}"; }
}

However, this isn't appropriate for production deployments if the DTO may contain PII (which shouldn't be captured in logs).

Always have easy way: Right Click > Generate > toString() > select template that you want. enter image description here

But then in the toString() method you aren't actually returning a String, are you? You'll have to return a String for this method to work.

public String toString() {
return "Name : " + this.name + " Height : " + this.height + " BirthDay : " + this.bday;
}