【发布时间】:2020-09-11 11:53:45
【问题描述】:
当我遇到这个问题时,我正在用 android 开发一个应用程序,我真的不知道这是一个已知的错误还是我应该提交错误报告。代码如下:
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
data class Status(val msg: String, val integer: Int, val msg2:String)
interface API {
@GET("/json/gson")
suspend fun gson(): Status
}
val gsonApiCalls = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://localhost:8080")
.build()
.create(API::class.java)
suspend fun main(){
val result = gsonApiCalls.gson()
println(result)
result.msg2?.let(::println) ?: println("Null result!")
}
本地服务器代码(Ktor):
import io.ktor.application.*
import io.ktor.response.*
import io.ktor.request.*
import io.ktor.routing.*
import io.ktor.http.*
import io.ktor.gson.*
import io.ktor.features.*
fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)
data class StandardResponse(val msg: String, val integer: Int, val msg2:String?)
@Suppress("unused") // Referenced in application.conf
@kotlin.jvm.JvmOverloads
fun Application.module(testing: Boolean = false) {
install(ContentNegotiation) {
gson {
}
}
routing {
get("/") {
call.respondText("HELLO WORLD!", contentType = ContentType.Text.Plain)
}
get("/json/gson") {
call.respond(StandardResponse("Hello",34, null))
}
}
}
结果是:
Status(msg=Hello, integer=34, msg2=null)
Null result!
上面的代码是我为测试这种行为而做的一个例子,但是当我第一次意识到这个“错误”出现在 Android 应用程序中时,我得到了 NullPointerException,我不明白为什么。
该应用程序正在使用远程节点服务器,并且发生了同样的事情。 Capture showing the linter thinks this can't be possible
如果这是一个错误,我应该将其报告给 Kotlin 还是 Retrofit?
【问题讨论】:
-
在您的客户端代码中,您有不可为空的
val msg2:String,但您从 ktor 发送null。这就是问题 -
是的,我知道,这是有意测试我描述的行为。问题是 Kotlin 字符串不应该为空,根据定义,如果它没有声明为字符串? (如图所示),但在这个例子中它是可能的。我想这是 Java 到 Kotlin 字符串转换的问题,但我仍然不明白这是怎么可能的。我的意思是,如果发生这种情况,不应该提前抛出异常吗?
-
是的,不可为空的字符串不应为空,因此当 gson 强制尝试将 null 解析为不可为空的字符串时会出现运行时异常。在编译时一切都很好,因为代码中没有任何地方可以将 null 传递给非 null 变量。但是如果你在运行时将 null 放入非 null 变量中,那么编译器就无法检查,对吧?
-
是的,我希望 gson 会抛出异常,但事实并非如此。它只是以某种方式将 null 解析为字符串
-
所以,总而言之,这不是改造、kotlin 和 gson 中的错误。如果这就是您要查找的全部内容,则会引发异常。如果您正在寻找一些解决方法,那么您必须更具体。
标签: kotlin nullpointerexception gson retrofit