Java
toString method
toString method in Java is used to provide
clear and concise information about Object in human readable format. Correctly
overridden toString method can help in logging
and debugging
of Java program by providing valuable and meaningful information. Since toString() is defined
in java.lang.Object class and its default implementation doesn't
provide much information, its always a best practice to override toString method in
sub class. In fact if you are creating value class or domain class e.g. Order, Trade or Employee, always override equals,
,hashCode,
compareTo
and toString method in Java. By default toString
implementation produce output in the form package.class@hashCode e.g. for
our toString() example, Country class’ toString() method
will print test.Country@18e2b22 where 18e2b22 is hashCode of object in hex format, if you
call hashCode method it will return 26094370, which is
decimal
equivalent of 18e2b22. This information is not very useful while troubleshooting
any problem. Let’s see a real life example where you are troubleshooting
network connectivity issues, in case of this you want to know which host and
port your system is trying to connect and if Socket or ServerSocket class only
print default toString information than its impossible
to figure out the actual problem, but with a decent toString
implementation they can print useful information like hostname
and port. In this Java tutorial we
will see some tips to override toString method with code examples.
How to override toString method in Java:
Overriding toString() method is similar to overriding
any method in Java, you need to follow rules
of method overriding. Any way there are many way to implement or override toString() method
e.g. You can write this method manually,
you can use IDE like Netbeans
and Eclipse
to generate toString method or you can use Apache commons
ToStringBuilder to generate toString method in
multiple styles like single line, multi-line etc. Here are few points to
remember while overriding toString() method in Java, which will help
you to get most from your toString() implementation.
formatted date e.g. dd-MM-yy instead of raw date
This is very helpful tip while overriding Java’s toString() method.
Since toString() of java.util.Date class does
not print formatted date and includes lots of details which is not always
necessary. If you are using a particular DateFormat
e.g. dd-MM-yy in your application, they you definitely want to see dates on that
format instead of default. IDE normally does not generate formatted Date
output and this is something you need to do by yourself but its worth of effort. See How
to print Date in ddMMyy format in Java for more details on formatting Date
in Java. You can either use SimpleDateFormat
class or Joda Date time library for this purpose.
Document
toString format
If your toString() method is not printing data in
terms of field=value, Its good idea to document format
of toString, especially for value objects like Employee or Student. For
example if toString() method of Employee prints "John-101-Sales-9846387321" than its
good idea to specify format as "name-id-department-contact", but at the
same time don't let your client extract information from toString() method and
you should always provide corresponding getter methods like getName(), getId(), getContact() etc,
because extracting information from toString() representation
of Object is fragile and error prone and client should always a cleaner way to
request information.
Use StringBuilder
to generate toString output
If you writing code for toString() method in Java, then use StringBuilder
to append individual attribute. If you
are using IDE like Eclipse,
Netbeans
or IntelliJ then also using StringBuilder and append() method
instead of + operator to generate toString method is
good way. By default both Eclipse and Netbeans generate toString method
with concatenation operator .
Use @Override annotation
Using @Override annotation while overriding method in Java is one of the
best practice in Java. But this tip is not as important as it was in case of
overriding equals()
and compareTo()
method, as overloading instead of overriding can create more subtle bugs there. Anyway it’s best to using @Override annotation.
contents of Array instead of printing array object
Array is an object in Java but it doesn’t override toString method and
when you print array, it will use default format which is not very helpful
because we want to see contents of Array. By the way this is another reason why
char[] array are preferred over String for storing sensitive data e.g.
password. Take a moment to see if printing content of array helps your user or
not and if it make sense than print contents instead of array object itself. Apart
from performance reason prefer Collection like ArrayList or HashSet
over Array for storing other objects.
Bonus Tips
Here are few more bonus tips on overriding
toString method in Java
1. Print output of toString in multiple line or single line based upon it
length.
2. Include full qualified name of class in toString
representation e.g. package.class to avoid any confusion/
3. You can either skip null values or show them, its better to leave them.
Sometime they are useful as they indicate which fields are null at the time of
any incident e.g. NullPointerException.
4. Use key value format like member.name=member.value as most of
IDE also follows that.
5. Include inherited members if you thing they provide must have information
in child class.
6. Sometime an object contains many optional and mandatory parameters like
we shown in our Builder
pattern example, when its not practically possible to print all fields in
those cases printing a meaningful information, not necessary fields is better.
toString Example in Java
We will use following class to demonstrate our toString examples for Netbeans, Eclipse and Apache's ToStringBuilder utility.
/**
* Java program to demonstrate How to override toString() method
in Java.
* This Java program shows How can you use IDE like Netbeans or Eclipse
* and Open source library like Apache commons ToStringBuilder to
* override toString in Java.
*
* @author Javarevisited.blogspot.com
*/
public class
Country{
private String
name;
private String
capital;
private long population;
private Date
independenceDay;
public Country(String name){
this.name = name;
}
public String
getName(){ return
name; }
public void setName(String
name) {this.name =
name;}
public String
getCapital() {return capital;}
public void setCapital(String
capital) {this.capital
= capital;}
public Date
getIndependenceDay() {return independenceDay;}
public void setIndependenceDay(Date independenceDay)
{this.independenceDay = independenceDay;}
public long getPopulation()
{ return
population; }
public void setPopulation(long population)
{this.population = population;
}
@Override
public String toString() {
return "Country{" + "capital="
+ capital + ",
population="
+ population + ",
independenceDay="
+ independenceDay + '}';
}
public void setIndependenceDay(String date) {
DateFormat format = new SimpleDateFormat("dd/MM/yyyy");
try {
this.independenceDay = format.parse(date);
} catch (ParseException
ex) {
Logger.getLogger(Country.class.getName()).log(Level.SEVERE,
null, ex);
}
}
public
static void
main(String args[]){
Country India = new Country("India");
India.setCapital("New Delhi");
India.setIndependenceDay("15/07/1947");
India.setPopulation(1200000000);
System.out.println(India);
}
}
toString
method created by Netbeans IDE
toString method generated by Netbeans IDE produce following output for above
class :
Country{capital=New
Delhi, population=1200000000, independenceDay=Fri Aug 15 00:00:00 VET 1947}
If you look
at above output you find that NetBeans does not generated formatted
Date for you, instead it calls toString() method of java.util.Date class.
toString()
code generated by Eclipse IDE:
By default Eclipse generates following toString method :
@Override
public String
toString() {
return "Country [name=" + name + ", capital=" + capital
+ ", population=" + population + ", independenceDay="
+ independenceDay + "]";
}
You can generate code for toString method in Eclipse by
clicking Source --Generate
toString(). It also provide several options like choosing code style e.g. concatenation operator or StringBuffer
etc. Here is the output of toString() method we
just created by Eclipse :
Country [name=India,
capital=New Delhi, population=1200000000,
independenceDay=Tue Jul 15 00:00:00 VET 1947]
Using
ToStringBuilder for overriding Java toString method
Along with many useful classes like PropertyUtils,
EqualsBuilder or HashCodeBuilder; Apache
commons provides another gem called ToStringBuilder which can generate
code for toString() method in different styles. Let’s
how does output of toString method looks like in simple style
and multi-line style.
Simple Style:
India,New Delhi,1200000000,Fri Aug 15 00:00:00 VET 1947
Multi-line style:
test.Country@f0eed6[
name=India
capital=New Delhi
population=1200000000
independenceDay=Fri Aug 15 00:00:00
VET 1947
]
NO_FIELD_NAMES_STYLE
test.Country@1d05c81[India,New
Delhi,1200000000,Fri Aug 15 00:00:00 VET 1947]
SHORT_PREFIX_STYLE
Country[name=India,capital=New Delhi,population=1200000000,independenceDay=Fri Aug 15 00:00:00 VET 1947]
ToStringStyle.DEFAULT_STYLE
test.Country@1d05c81[name=India,capital=New
Delhi,population=1200000000,independenceDay=Fri
Aug 15 00:00:00 VET 1947]
Similarly Google’s open source library Guava also provide convenient API
to generate code for toString method in Java.
When toString method is invoked in Java
toString is a rather special method and
invoked by many Java API methods like println(), printf(), loggers, assert
statement, debuggers in IDE, while printing collections and with concatenation operator. If subclass doesn't override toString() method
than default implementation defined in Object class gets invoked. Many
programmers either use logging API like Log4J or java.util.Logger to print
logs and often pass Object there. logger.info("Customer
not found : " + customer) and if Customer doesn't
override toString and print meaningful information
like customerId, customerName etc than
it would be difficult to diagnose the problem. This why its always good to
override toString in Java.let's see some benefits
of doing this.
Benefits
of overriding toString method:
1) As discussed above, correctly overridden toString helps in debugging
by printing meaningful information.
2) If value objects are stored in Collection than printing
collection will invoke toString on stored object which can
print very useful information.One of the classic example of not overriding toString method is
Array in Java, which prints default implementation rather than contents of
array. Though there are couple of ways to print contents of array using Arrays.toString() etc but
given Array is an object in Java, would have been much better if Array know how
to print itself much like Collection classes like List
or Set.
3) If you are debugging
Java program in Eclipse than using watch or inspect feature to look object, toString will
definitely help you.
These are just some of the benefits you get by implementing or overriding
toString method in Java, there are
many more which you get and learn by yourself. I hope these tips will help you
to get most of your toString implementation. Let us know if you any unique toString() tips which
has helped you in your Java application.
Other Java String articles from Javarevisited Blog
Tidak ada komentar:
Posting Komentar