Convert Class Object to Human Readable String - java

Is there any way in which I can automatically convert a Custom Class Object into a human readable string?
e.g. consider the following class:
class Person {
String Name;
int Salary;
...
}
Person p = new Person();
p.setName("Tony");
p.setSalary(1000);
I need to get something like:
Person: Name="Tony", Salary=1000

Importing Commons Lang you could use ToStringBuilder
Check method reflectionToString(java.lang.Object), this will create automatically the representation you are expecting.
This code:
Person p = new Person();
p.setName("Tony");
p.setSalary(1000);
System.out.println(ToStringBuilder.reflectionToString(p));
results this string:
Person#64578ceb[Name=Tony,Salary=1000]

sure you can override the toString method of class.
as follow:
class Person {
String name;
int salary;
...
#Override public String toString() {
return "Person: Name='" + name + "', Salary=" + salary;
}
}
refer for more details https://blogs.oracle.com/CoreJavaTechTips/entry/writing_tostring_methods_tech_days

This is basically what toString is for. But given you want this done automatically, you can create some general service that can do it. Use reflection to iterate all fields, and then print each one's name and value. Simplest way to print their values would be by using their toString, but you can also pass them into that printing service recursively on some cases (you'll have to find the halt condition, of course).
For example, on some class PrintUtils have:
public static void printFields(Object o) {
System.out.print(o.getClass.getSimpleName() + ": ");
for (Field field : o.getClass().getDeclaredFields()) {
field.setAccessible(true); // you also get non-public fields
System.out.print(field.getName() + " = " + field.get(o) + ", ");
}
}
You'll have to handle exceptions etc. and possibly better format the output, of course. Also, this only print fields declared in the current class. If you want fields declared higher in the inheritance hierarchy, you'll have to work a bit more. Lastly, using reflection is much slower than just having a regular toString. If using toString is possible, it is preferable.

I think you could use ToStringBuilder that is part of commons-lang.

One way to do it is to rely on Apache Commons BeanUtils.describe. This will produce a Map of bean's properties, which converts to a string nicely via Map.toString. If you want something more custom, you'll need to dig into the reflection API.

You can use message format from java :
https://docs.oracle.com/javase/tutorial/i18n//message.html
seperate variable by - and there you have a humanreadable string of your class!

class Person {
String Name;
int Salary;
...
#Override
public String toString() {
return "Person: Name = " + Name + "," +
"Salary="+Salary;
}
}
Person p = new Person();
p.setName("Tony");
p.setSalary(1000);
System.out.println(p.toString());

Related

How to get Array List to show three indexes at one time in android studio? [duplicate]

Sounds a little stupid, but I need help on my toString() method and it is very irking.
I tried looking up online because the toString is the one where it is screwing up and "not finding Kid constructor #2" even though it is there and I would even do something else and it doesn't work.
Ok that was a lot so here is my code:
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
Ok So my toString above (I know, my third parameter is off, should be a String) is off. If I hardcode a value in for the third thing it goes haywire and says it can't find this (up above). So how can I get the date and break it up?
Class calling this is below
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
I tried researching multiple constructors and it really didn't help.
I tried researching toString() methods, and tried using previous toString() methods logic that I created previous but this is brand new so it never worked.
Help?
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
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.
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.
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 + '\'' +
'}';
}
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.
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
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()
}
}
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.
if you are use using notepad:
then
public String toString(){
return ""; ---now here you can use variables which you have created for your class
}
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.
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;
}

Hibernate retuns object not list [duplicate]

Sounds a little stupid, but I need help on my toString() method and it is very irking.
I tried looking up online because the toString is the one where it is screwing up and "not finding Kid constructor #2" even though it is there and I would even do something else and it doesn't work.
Ok that was a lot so here is my code:
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
Ok So my toString above (I know, my third parameter is off, should be a String) is off. If I hardcode a value in for the third thing it goes haywire and says it can't find this (up above). So how can I get the date and break it up?
Class calling this is below
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
I tried researching multiple constructors and it really didn't help.
I tried researching toString() methods, and tried using previous toString() methods logic that I created previous but this is brand new so it never worked.
Help?
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
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.
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.
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 + '\'' +
'}';
}
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.
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
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()
}
}
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.
if you are use using notepad:
then
public String toString(){
return ""; ---now here you can use variables which you have created for your class
}
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.
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;
}

Return two string in toString function

#Entity
public class Person {
private Integer id = null;
private String name = null;
private String price = null;
private Date created = null;
// String Representation:
#Override
public String toString() {
return name;
// I want to return name and price
}
I want to return name and price in toString function ? This is right to return more than one string in toString function. If you make relation in other's Entity ManyToMany ?
Please suggest me if I am doing right or wrong as I want to show these fields in other entity where I make relations.
Thanks!
Usually the toString() method returns a string-representation of the object and not the object's members themself. So if you need a representation of name and price you could do
return "Name: " + name + ", Price: " + price;
If you really want to receive the members name and price you should generate getters for those and use them in the caller.
Another possibility is to "wrap" the two strings in some sort of data class.
This is right to return more than one string in toString function. If you make relation in other's Entity ManyToMany ?
That could be
#Override
public String toString() {
return "Name :" +name + " Price : "+price;
}
If you still have more Objects related to it, just append in the last. So that you won't loose information.
You can do it like this:
return name+" "+price;
You can create another method to return both.
you can return String array as well so that you don't need to split the string if you need to perform any operation on name and price.
You can use a StringBuilder and build up your composed String efficiently from both the name, the price and whatever you want.
Here the documentation.
Anyway, the response is no, you cannot send back two strings, but you can return a string that is a composition of the others.

How to return the name of the instance of a class in Java

I am a beginner in Java (and programming), and there should be a simple answer to this, but I could not find it. I want to write a code that would print the value of the reference name of an instance variable. For example:
Public class Person {
Person() {
//attributes, height, weight, etc.
}
Person Person1 = new Person();
}
I would like to write a line of code that would produce something to the tune of
"The attribute of Person1 is..."
Something to the tune of System.out.println("The attribute of Person1 " +(????)+" is ....")
I was unable to find or create a method that would return the name Person1.
"Person1" is not the name of the instance, but instead is the name of a variable that holds the reference to the instance. The instance itself has no name. You will have to give it an attribute of name if you care to keep it.
public class Person {
private final String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
then you can do:
Person person1 = new Person("Jeff");
System.out.println("Person1's name is: " + person1.getName());
The output of that will be:
Person1's name is: Jeff
It is not generally possible to do exactly what you want. I don't think variable names are even compiled into the classes.
It can be done with compile time annotations but it's not trivial.
To be able to do that you should override the toString() function
Something like this
/* Returns the string representation of your class object .*/
#Override
public String toString() {
return "The attributes of this person are :height - " + height + " weight - " + weight + // you are print out all your properties.
}
Now whenver you want to print the object you can do
System.out.println(person1);
I'm not sure how familiar you are with programming languages in general. I see you say you are new to Java, so I'll start there. Java, like many object-oriented languages, uses inheritance when you create classes. In Java, when you define a class you can use the "extends" keyword to sub-class and use or override any methods in the parent class. Now, in Java, ALL classes automatically inherit from this class called Object.
This is very useful to know, because Object contains a few useful methods, most notably of them is "toString()". You do not need to use extends to get these methods btw. Now, toString on its own is not useful, but you can override it to print out what you want.
public class Person
{
String name;
int age;
Person(String name, int age)
{
this.name = name;
this.age = age;
}
#Override
public String toString()
{
return "Name is: " + name + "and age is: " + age";
}
}
Notice the toString() method I defined there? Anytime you call this method on an object, you will get that string printed out. So for instance, in your example:
Person person1 = new Person("Ford Prefect", 42);
System.out.println(person1.toString()); //Will print what we defined in toString.
You don't even need the .toString(), just person1 because the JVM will realize you meant to use toString. If you use IntelliJ IDE, you can do Alt + Insert and select toString() to override it. IDEs are wonderful tools to help you be more efficient. Good luck!

How to override toString() properly in Java?

Sounds a little stupid, but I need help on my toString() method and it is very irking.
I tried looking up online because the toString is the one where it is screwing up and "not finding Kid constructor #2" even though it is there and I would even do something else and it doesn't work.
Ok that was a lot so here is my code:
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
Ok So my toString above (I know, my third parameter is off, should be a String) is off. If I hardcode a value in for the third thing it goes haywire and says it can't find this (up above). So how can I get the date and break it up?
Class calling this is below
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
I tried researching multiple constructors and it really didn't help.
I tried researching toString() methods, and tried using previous toString() methods logic that I created previous but this is brand new so it never worked.
Help?
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
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.
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.
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 + '\'' +
'}';
}
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.
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
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()
}
}
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.
if you are use using notepad:
then
public String toString(){
return ""; ---now here you can use variables which you have created for your class
}
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.
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;
}

Categories

Resources