使 String.format("%s", arg) 以不同于 "null" 的方式显示空值参数
Posted
技术标签:
【中文标题】使 String.format("%s", arg) 以不同于 "null" 的方式显示空值参数【英文标题】:Make String.format("%s", arg) display null-valued arguments differently from "null" 【发布时间】:2013-12-05 15:59:55 【问题描述】:考虑一个 bean 的自定义 toString()
实现:
@Override
public String toString()
String.format("this is %s", this.someField);
如果someField
为空,则生成this is null
。
有没有办法将空值参数的默认null
字符串表示形式覆盖到另一个文本,即?
而不在toString
方法中显式调用replaceAll(...)
?
注意:该 bean 继承自可以实现 Formattable
(http://docs.oracle.com/javase/7/docs/api/java/util/Formattable.html) 的超类,但我似乎不明白如何实现这一点。
编辑:为了举例,sn-p 被过度简化了,但我不是在寻找三元运算符解决方案someField==null ? "?" : someField
,因为:
toString()
可能(可能)涉及很多字段,因此检查所有字段过于繁琐且不够流畅。
我无法控制的其他人(如果有的话)正在编写他们自己的子类。
如果一个方法被调用并返回 null,这意味着调用该方法两次或声明一个局部变量。
相反,可以使用Formattable
接口或使用一些自定义Formatter
(顺便说一句是final
)来完成任何事情吗?
【问题讨论】:
我愿意String.format("this is %s", this.someField==null?"?":this.someField);
或与番石榴:String.format("this is %s", Objects.firstNotNull(this.someField, "?"));
我总是很喜欢firstNotNull
,尤其是。类似的实现一些SQL方言,但是Guava的依赖太重,属于Utils类的依赖而不是pojo,imo的依赖。
@VH-NZZ 有一些很棒的解决方案。确定不能选择接受?
@KimKern 大多数(如果不是全部)以某种方式解决问题并最终产生与问题兼容的结果,尽管需要付出一些代价。话虽如此,我客观上不能断言我可以选择 one 答案作为真正优秀的,因此:不,在这个阶段我恐怕不能。
【参考方案1】:
使用 java 8,您现在可以为此使用 Optional 类:
import static java.util.Optional.ofNullable;
...
String myString = null;
System.out.printf("myString: %s",
ofNullable(myString).orElse("Not found")
);
【讨论】:
要同时申请 'empty' 值,可以使用 'filter(s -> !s.isEmpty())' 扩展如下: System.out.printf("myString: % s", ofNullable(myString).filter(s -> !s.isEmpty()).orElse("未找到")【参考方案2】:对于不需要外部库的 Java 7 解决方案:
String.format("this is %s", Objects.toString(this.someField, "?"));
【讨论】:
【参考方案3】:在我看来,最好的解决方案是使用 Guava 的 Objects 方法 firstNonNull。如果 someField 为空,以下方法将确保您将打印一个空字符串。
String.format("this is %s", MoreObjects.firstNonNull(this.someField, ""));
Guava docs.
【讨论】:
String.format("this is %s", StringUtils.defaultIfBlank(this.someField, ""));
如果 Apache StringUtils 恰好在您的类路径上,则可以解决问题。【参考方案4】:
这个主题有点晚了,但这可能是一个看起来很干净的解决方案: 首先,创建自己的格式方法...
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);
那么,随意使用吧……
@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);
这消除了对多个难以阅读的三元运算符的需要。
【讨论】:
... 但暗示依赖于您的formatNull
方法。
当然!除非前面提到的案例特定于某些输出策略类,否则该方法可以在策略本身中私有定义。那么就不会有依赖问题了。如果它在应用程序中的许多地方使用,那么是的,它需要放在某个库/实用程序类中。【参考方案5】:
如果您不想使用replaceAll()
,您可以为someField
分配一个默认文本(字符串)。
但如果有时间这可能会再次分配null
。所以你可以对这种情况使用验证
this.someField == null ? "defaultText" : this.someField
【讨论】:
【参考方案6】:为避免重复三元运算符,您可以将其包装在更易读的方法中,该方法将检查您的对象是否为null
,如果为真则返回一些默认值
static <T> T changeNull(T arg, T defaultValue)
return arg == null ? defaultValue : arg;
用法
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, ""));
输出:
field is
id is -1
id is
【讨论】:
【参考方案7】:你可以这样做
String.format("this is %s", (this.someField==null?"DEFAULT":this.someField));
【讨论】:
再次,这是使用三元运算符。还是谢谢。【参考方案8】:从 java 7 开始,您可以使用Objects.toString(Object o, String nullDefault)
。
应用于您的示例:String.format("this is %s", Objects.toString(this.someField, "?"));
【讨论】:
【参考方案9】: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);
然后使用方法,ok
【讨论】:
【参考方案10】:要保留someField
的原始值(如果null 是有效值),您可以使用ternary operator。
String.format("This is %s", (this.someField == null ? "unknown" : this.someField));
【讨论】:
以上是关于使 String.format("%s", arg) 以不同于 "null" 的方式显示空值参数的主要内容,如果未能解决你的问题,请参考以下文章
C#中 s +=string.Format("0,1*1,1=2,-4",j,i,j*i)是啥意思?