java - String.format 在 Kotlin 和 Java 中的工作很奇怪
问题描述
我试图将代码库从 Java 迁移到 Kotlin。但我在 String.format 中发现了奇怪的行为。
我在 Kotlin 和 Java 中都有相同的代码(和功能)。
fun callScriptMethod(methodName: String, vararg args: Any): String {
var format = methodName
if (!format.contains("javascript:")) {
format = String.format("javascript:%s", format)
}
val objects = mutableListOf<Any>()
for (arg in args) objects.add(arg)
if (!objects.isEmpty()) {
format += "("
var i = 0
val icnt = objects.size
while (i < icnt) {
format += "\'%s\'"
if (i != icnt - 1) {
format += ", "
}
i++
}
format += ")"
} else {
format += "()"
}
val message = String.format(Locale.getDefault(), format, args)
return message
}
public static String callScriptMethod(String methodName, Object... args) {
String format = methodName;
if (!format.contains("javascript:")) {
format = String.format("javascript:%s", format);
}
List<Object> objects = Arrays.asList(args);
if (!objects.isEmpty()) {
format += "(";
for (int i = 0, icnt = objects.size(); i < icnt; i++) {
format += "\'%s\'";
if (i != icnt - 1) {
format += ", ";
}
}
format += ")";
} else {
format += "()";
}
String message = String.format(format, args);
return message;
}
和一些测试代码。
fun main() {
val result = Java.callScriptMethod("nativeCallback", "1", "d8d8441n24n134n",
"dasqhjidhkdhaskjdfhawoiudnqwaidnqwioldjnqawskld:djoashdojashdlkjasdjhas", "0")
println(result)
val result2 = Kotlin.callScriptMethod("nativeCallback", "1", "d8d8441n24n134n",
"dasqhjidhkdhaskjdfhawoiudnqwaidnqwioldjnqawskld:djoashdojashdlkjasdjhas", "0")
println(result2)
}
我可以预期结果是javascript:nativeCallback('1', 'd8d8441n24n134n', 'dasqhjidhkdhaskjdfhawoiudnqwaidnqwioldjnqawskld:djoashdojashdlkjasdjhas', '0')
。
但是 Kotlin 的版本有例外MissingFormatArgumentException
。
因此,我尝试调试这些代码以知道格式已成功生成。
爪哇:javascript:nativeCallback('%s', '%s', '%s', '%s')
科特林:javascript:nativeCallback('%s', '%s', '%s', '%s')
两者都是相同的结果并且具有相同的结果args
但具有不同的结果。
javascript:nativeCallback('1', 'd8d8441n24n134n', 'dasqhjidhkdhaskjdfhawoiudnqwaidnqwioldjnqawskld:djoashdojashdlkjasdjhas', '0')
Exception in thread "main" java.util.MissingFormatArgumentException: Format specifier '%s'
at java.util.Formatter.format(Formatter.java:2519)
at java.util.Formatter.format(Formatter.java:2455)
at java.lang.String.format(String.java:2981)
at Kotlin.callScriptMethod(Kotlin.kt:31)
at TestKt.main(test.kt:11)
at TestKt.main(test.kt)
所以,我想知道是什么问题。我能怎么做?
解决方案
由于 vararg 进入函数体后就变成了一个数组,因此您必须使用扩展运算符才能将其作为 vararg 传递。https://kotlinlang.org/docs/reference/functions.html#variable-number-of-arguments-varargs
当我们调用一个可变参数函数时,我们可以一个接一个地传递参数,例如 asList(1, 2, 3),或者,如果我们已经有一个数组并且想要将它的内容传递给函数,我们使用扩展运算符(以 * 为数组前缀):
val message = String.format( format, *args)
与 Java 的不同之处在于 Java 实际上允许将数组作为 vararg 直接传递,请参阅此 SO 帖子:我可以将数组作为参数传递给 Java 中具有可变参数的方法吗?
ie Object...
in Java 在技术上与 相同,JavaObject[]
中没有“真正的”可变参数,而vararg
在 Kotlin 中是真正不同的东西。
推荐阅读
- java - 如何从 firebase 服务器获取图像和视频到我的博客应用程序?
- javascript - 取消组件WillUnmount中的任务
- java - 如何使用 AnimationTimer 移动节点?
- python - Python中的图像到十六进制数据的转换
- asp.net-core - ASPNET MVC 过滤器、WebAPI 过滤器、ASPNET Core MVC 过滤器,是三个不同的东西吗?
- javascript - 为什么在使用类时我的 var 未定义?
- php - 如何在 laravel 模型中使用多个工具
- java - 如何在 RecyclerView 中快速滚动时解决位置编号不匹配问题?
- bash - 为什么即使前面的命令成功,`||` 后面的命令也会执行?
- java - Java / Spring引导应用程序如何处理终止信号