String.format打印地址而不是varargs中的字符串

时间:2017-07-29 17:59:48

标签: java

我正在尝试编写一个包装器方法,以使用方法名称和用户ID为我的日志消息添加前缀。我使用String.format来组成消息结构,但问题来自于String.format()

对varargs的解释
private String logMessage(@NonNull String methodName, @NonNull String userId, @NonNull String message, Object... arguments) {
    //String temp = String.format(message, arguments);
    //String msg = String.format("%s:: User:%s : %s", methodName, userId, temp);<--This works
    String msg = String.format("%s:: User:%s : " + message, methodName, userId, arguments);<--This prints address of arguments object
   log.info(msg);
}

将上述方法称为

logMessage(methodName, userId, "Some text here: %s",
                "test"));

以上电话打印

someMethod:: User:1266 : Some text here: [Ljava.lang.Object;@705a8dbc

为什么String.format打印字符串“test”的地址?

2 个答案:

答案 0 :(得分:0)

argument对象实际上是一个对象数组。当你在这种对象上调用toString()方法时,你通常会得到类似的东西:

[Ljava.lang.Object;@705a8dbc

实际上,[Ljava.lang.Object是一个java字节码类型描述符,意思是“这是java.lang.Object类型的数组('[')('Ljava.lang.Object')

705a8dbc

这是数组的hashCode十六进制值。如果查看这个SO question,您可以看到,在接受的答案中,文档说hashCode()方法必须返回唯一标识符,并且通常通过将对象的内部地址转换为整数,但不是必需的

如果要获取数组中每个对象的toString()值,应使用:

Arrays.toString(argument);

这个静态方法返回一个字符串,其中包含用逗号分隔的每个对象的所有toString值,方括号之间如下:

[null, null, null, null, null] // Example with System.out.println(Arrays.toString(new Object[5]));

答案 1 :(得分:0)

我看到了问题,varargs实际上是一个数组而String.format没有扩展参数。我通过在消息之后传递方法名称和用户ID来解决这个问题:

post_save

并将方法修改为:

logMessageWithPrefix("Some text here: %s",
                methodName, userId, "test")

不是理想的解决方案,因为ppl可能不会像方法所期望的那样传递methodname和userid,但会在方法上添加一些注释以防止混淆。