【问题标题】:Stricter String.format that does not ignore extra arguments?更严格的 String.format 不会忽略额外的参数?
【发布时间】:2018-01-12 19:59:18
【问题描述】:

Java 的String.format 默默地忽略传递的额外参数,这些参数未在格式字符串中使用,但如果传递的参数较少或无效,则会失败。当传递更多参数时,有没有办法处理这种情况?

如果参数多于格式说明符,则忽略多余的参数

https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#format-java.lang.String-java.lang.Object...-

private static void doStuff(Stuff stuff, String details, Object... args) {
    if(stuff.someCondition()) {
        try {
            details = String.format("Details: " + details, args);
        } catch (Exception ex) { //No Exception thrown when args are not used by
            String arguments = Arrays.stream(args)
                    .map(Objects::toString)
                    .collect(joining(";"));
            details = String.format("Details: %s Args: %s", details, arguments);
        }
    }
    stuff.process(details);
}

private static void foo() {
    Stuff stuff = new Stuff();
    doStuff(stuff, "blah blah %s ", "blah"); // No exception, works as expected
    doStuff(stuff, "blah blah %s %s", "blah"); // Fails as expected and args are printed
    doStuff(stuff, "blah blah %s", "blah", "blah"); // Silently ignores. How to handle this case?
}

【问题讨论】:

  • 您能告诉我们您要处理哪种情况吗?
  • @YCF_L 添加示例
  • 你想用额外的参数做什么?
  • 你可以简单地统计以%开头的子串的实例,排除%%,并检查结果数字是否与参数的长度匹配
  • 这不是一个简单的问题。考虑一下:String.format("%1$s %1$s", 1, 2)。它应该因为2 未使用而失败吗? String.format("%2$s", 1, 2)呢?

标签: java string string-formatting


【解决方案1】:

在不计算或解析% 的情况下采用不同的方法。不过效率不高。

public static String safeFormat(String formatStr, Object... args) {
    List<Object> objects = Arrays.asList(args);
    // https://commons.apache.org/proper/commons-lang/javadocs/api-3.7/org/apache/commons/lang3/mutable/MutableBoolean.html
    MutableBoolean isCalled = new MutableBoolean(false);
    objects.add(new Object(){
        @Override
        public String toString() {
            isCalled.setTrue();
            return "";
        }
    });
    String result = String.format(formatStr+"%s", objects.toArray());
    if(isCalled.isFalse()) {
        throw new IllegalArgumentException("Not all arguments used by formatter");
    }

    return result;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 2019-07-07
    相关资源
    最近更新 更多