|
 |
|
|
toString() Generator: Code Styles
Code style determines how the generated method works and what classes it uses. There are several code styles available to chose from the combo box in generator's
dialog:
-
String concatenation
This style uses simple sum expressions so it's very efficient (compiler uses StringBuilder/StringBuffer to optimize the code) and relatively easy to read and modify. Here's an example outcome in the simplest case:
return "FooClass [aFloat=" + aFloat + ", aString=" + aString + ", anInt=" + anInt
+ ", anObject=" + anObject + "]";
With "Skip null values" option turned on, the code becomes a little harder to read:
return "FooClass [aFloat=" + aFloat + ", "
+ (aString != null ? "aString=" + aString + ", " : "")
+ "anInt=" + anInt + ", "
+ (anObject != null ? "anObject=" + anObject : "") + "]";
-
StringBuilder/StringBuffer
This style uses StringBuilder if the project is compatible with JDK1.5 or later and StringBuffer otherwise. StringBuilder is faster (because of lack of synchronization), but only available since JDK1.5.
StringBuilder builder = new StringBuilder();
builder.append("FooClass [aFloat=");
builder.append(aFloat);
builder.append(", aString=");
builder.append(aString);
builder.append(", anInt=");
builder.append(anInt);
builder.append(", anObject=");
builder.append(anObject);
builder.append("]");
return builder.toString();
The "Skip null values" option doesn't obfuscate the code as much as previously:
StringBuilder builder = new StringBuilder();
builder.append("FooClass [aFloat=");
builder.append(aFloat);
builder.append(", ");
if (aString != null) {
builder.append("aString=");
builder.append(aString);
builder.append(", ");
}
builder.append("anInt=");
builder.append(anInt);
builder.append(", ");
if (anObject != null) {
builder.append("anObject=");
builder.append(anObject);
}
builder.append("]");
return builder.toString();
-
StringBuilder/StringBuffer with chained calls
Style very similar to the previous one only that append methods are called in chain. This makes the code shorter and probably easier to read.
StringBuilder builder = new StringBuilder();
builder.append("FooClass [aFloat=").append(aFloat).append(", aString=").append(aString)
.append(", anInt=").append(anInt).append(", anObject=").append(anObject).append("]");
return builder.toString();
With "Skip null values" switched on, the chain must be broken:
StringBuilder builder = new StringBuilder();
builder.append("FooClass [aFloat=").append(aFloat).append(", ");
if (aString != null) {
builder.append("aString=").append(aString).append(", ");
}
builder.append("anInt=").append(anInt).append(", ");
if (anObject != null) {
builder.append("anObject=").append(anObject);
}
builder.append("]");
return builder.toString();
-
String.format()/MessageFormat
This style is very pleasant for relatively short list of elements, but with longer ones it becomes hard to see which fields are associated with which variables. Unfortunately, the "Skip null values" option cannot be used with this style.
return String.format("FooClass [aFloat=%s, aString=%s, anInt=%s, anObject=%s]",
aFloat, aString, anInt, anObject);
Because there's no String.format() in JDK 1.4 and ealier, MessageFormat.format() is used instead:
return MessageFormat.format("FooClass [aFloat={0}, aString={1}, anInt={2}, anObject={3}]",
new Object[] { new Float(aFloat), aString, new Integer(anInt), anObject });
-
This style uses an external class to build a result string. It can use classes that fulfill the following conditions:
- Provide a public constructor taking a single
Object as parameter - it will be passed an object for which the toString() method is called
- Provide methods for appending member information - these are methods with specified name, that take an
Object and (optionally) a String (in any order)
- Provide a method for retrieving result - that is a method taking no arguments and returning a
String
Custom builder requires some additional configuration to work properly. All necessary options can be entered in a dialog box showing up after clicking 'Configure...' button. These options include:
-
Builder class - a fully qualified name of a class to use. It can be typed in manually or selected from a class search dialog box
(in this case it's automatically checked if selected class meets the requirements).
It can be a class declared either directly in current project or in one of included libraries -
it just has to be accessible on the build path. For example, ToStringBuilder from the Apache Commons Lang library or
ToStringCreator from the Spring Framework work very well with this mechanism.
-
Builder label - any valid java identifier. It will be used to reference the builder object.
-
Append method - the name of methods to use for appending items. If the class provides many methods with this name, methods taking two arguments (one of them must be
String ) are preferred over those taking a single argument (additionally, the String argument shall preferably be the first one). If there are versions of the method that take specific argument types, they are also used when possible.
-
Result method - the name of a method to use for retrieving final result.
-
Chain invocations - determines whether calls to the append methods should form chains. This option takes effect only for methods that have proper return type (that is, the builder class, or a subclass).
For example, suppose your builder class looks like this:
package org.foo.ToStringBuilder2;
public class ToStringBuilder2 {
public ToStringBuilder2(Object o) {...}
public ToStringBuilder2 appendItem(String s, Object o) {...}
public ToStringBuilder2 appendItem(String s, float f) {...}
public String getString() {...}
}
Of course in this case builder class should be set to "org.foo.ToStringBuilder2" , builder label can be for example "builder" , append method is "appendItem" and result method is "getString" . With chain invocations selected, generated method will look like this:
ToStringBuilder2 builder = new ToStringBuilder2(this);
builder.append("aFloat", aFloat).append("aString", aString).append("anInt", new Integer(anInt))
.append("anObject", anObject);
return builder.getString();
Note that a primitive variable anInt was passed to the builder using wrapper type. This is done for projects using JDK 1.4 and earlier (for later JDKs the compiler does it automatically). In case of aFloat there was a specific method in builder class so no wrapping was required.
Generate toString() dialog
toString() Generator: Format Templates
toString() Generator: Content Listing
|
|
|