With java 8 you can now use Optional class for this:
import static java.util.Optional.ofNullable;
...
String myString = null;
System.out.printf("myString: %s",
ofNullable(myString).orElse("Not found")
);
Question
Consider the custom toString()
implementation of a bean:
@Override
public String toString() {
String.format("this is %s", this.someField);
}
This yields this is null
if someField
is null.
Is there a way to override the default null
string representation of null-valued arguments to another text, i.e., ?
without calling explicitly replaceAll(...)
in the toString
method?
Note: The bean inherits from a superclass that could implement Formattable
(http://docs.oracle.com/javase/7/docs/api/java/util/Formattable.html) but I just don't seem to understand how to make this work.
EDIT: The snippet is over-simplified for the sake of example but I'm not looking for ternary operator solutions someField==null ? "?" : someField
because:
toString()
so checking all fields is too cumbersome and not fluent.Rather, can anything be done using the Formattable
interface or having some custom Formatter
(which is final
btw.)?
No correct solution
OTHER TIPS
With java 8 you can now use Optional class for this:
import static java.util.Optional.ofNullable;
...
String myString = null;
System.out.printf("myString: %s",
ofNullable(myString).orElse("Not found")
);
For a Java 7 solution that doesn't require external libraries:
String.format("this is %s", Objects.toString(this.someField, "?"));
The nicest solution, in my opinion, is using Guava's Objects method, firstNonNull. The following method will ensure you will print an empty string if someField is ever null.
String.format("this is %s", MoreObjects.firstNonNull(this.someField, ""));
A bit late on the subject, but this could be a quite clean-looking solution : First, create your own format method...
private static String NULL_STRING = "?";
private static String formatNull(String str, Object... args){
for(int i = 0; i < args.length; i++){
if(args[i] == null){
args[i] = NULL_STRING;
}
}
return String.format(str, args);
}
Then, use it as will...
@Test
public void TestNullFormat(){
Object ob1 = null;
Object ob2 = "a test";
String str = formatNull("this is %s", ob1);
assertEquals("this is ?", str);
str = formatNull("this is %s", ob2);
assertEquals("this is a test", str);
}
This eliminates the need for multiple, hard-to-read, ternary operators.
If you don't want to use replaceAll()
, You can assign a default text(String) for someField
.
But if some time this may assign null
again. So you can use validation for that case
this.someField == null ? "defaultText" : this.someField
To avoid repeating ternary operator you can wrap it in more readable method that will check if your object is null
and return some default value if it is true like
static <T> T changeNull(T arg, T defaultValue) {
return arg == null ? defaultValue : arg;
}
usage
String field = null;
Integer id = null;
System.out.printf("field is %s %n", changeNull(field, ""));
System.out.printf("id is %d %n", changeNull(id, -1));
System.out.printf("id is %s %n", changeNull(field, ""));
output:
field is
id is -1
id is
You could just do
String.format("this is %s", (this.someField==null?"DEFAULT":this.someField));
From java 7, you can use Objects.toString(Object o, String nullDefault)
.
Applied to your example: String.format("this is %s", Objects.toString(this.someField, "?"));
public static String format(String format, Object... args){
for (int i=0;i<args.length;i++){
if (args[i]==null) args[i]="";
}
return String.format(format,args);
}
then use the method ,ok
To keep the original value of someField
(in case null is a valid value), you can use a ternary operator.
String.format("This is %s", (this.someField == null ? "unknown" : this.someField));