String.format在Kotlin和Java中工作得很奇怪
我试图将代码库从Java迁移到Kotlin。但我在String.format中发现了奇怪的行为 我在Kotlin和Java中都有相同的代码(和特性)String.format在Kotlin和Java中工作得很奇怪,java,kotlin,string-formatting,Java,Kotlin,String Formatting,我试图将代码库从Java迁移到Kotlin。但我在String.format中发现了奇怪的行为 我在Kotlin和Java中都有相同的代码(和特性) fun callScriptMethod(methodName: String, vararg args: Any): String { var format = methodName if (!format.contains("javascript:")) { format = String
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
}
我可以预期结果是javascript:nativeCallback('1','d8d8441n24n134n','dasqhjidhkdhaskjdfhawoiudnqwaidnqwioldjnqawskld:djoashdojashdlkjasdjas','0')
但是Kotlin的版本有异常MissingFormatArgumentException
因此,我尝试调试这些代码,以了解格式是否成功生成
Java:javascript:nativeCallback(“%s”、“s”、“s”、“s”)
Kotlin: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一旦进入函数体就变成了数组,因此必须使用spread操作符才能将其作为vararg传递 当我们调用vararg函数时,我们可以逐个传递参数,例如asList(1、2、3),或者,如果我们已经有一个数组,并且想要将其内容传递给函数,我们可以使用扩展运算符(在数组前面加*): 与Java的区别在于,Java实际上允许将数组作为vararg直接传递,请参见本文:
i、 e.
Object…
在Java中与Object[]
在技术上是相同的,Java中没有“真正的”vararg,而vararg
在Kotlin中是一个真正不同的东西。有什么原因让你构建一个格式字符串而不是直接包含arg?对象的意义是什么?@shmosel我使用String.format的前提是参数可能会改变,但现在我认为使用StringBuilder尝试concat会更好。如果没有特殊的解决方案,那么这样做也不会太糟糕。是否使用StringBuilder无关紧要。你所做的同样昂贵。如果/否则也没有意义。它们都会为空列表生成相同的结果。请尝试String.format(format,*args)
。要将数组作为vararg
传递,必须显式地将其解压缩。
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')
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)
val message = String.format( format, *args)