无法从Java调用Kotlin的扩展属性

时间:2019-07-16 11:26:33

标签: java android kotlin

Android Studio 3.4

这是我的科特琳课:

open class DefaultRestClientCallback<T> : Callback<T> {

    val Response<*>.errorResponse: ErrorResponse
        get() = ErrorUtils.parseError(this)



    override fun onResponse(call: Call<T>, response: Response<T>) {

正如您在这里看到的,我具有属性扩展名:

errorResponse

在另一个Kotlin类(Test.kt)中,我这样称呼:

class Test {


    fun test() {
        TransportService.login("email",
            "pass", object : DefaultRestClientCallback<JsonElement>() {

                override fun onTangoResponse(response: Response<*>) {
                    val isSuccessful = response.isSuccessful
                    if (isSuccessful) { // code >= 200 && code < 300;
                    } else {
                        val errorResponse = response.errorResponse
                    }
                }
            })
    }
}

很好,工作正常。

现在,我需要从Java文件(暂时无法将其转换为Kotlin )中调用扩展属性。 我试试这个:

TransportService.login("email", "pass", new DefaultRestClientCallback<JsonElement>() {

    @Override
    public void onTangoResponse(@NotNull Response<?> response) {
        boolean isSuccessful = response.isSuccessful();
        if (isSuccessful) { // code >= 200 && code < 300;
        } else {
            ErrorResponse errorResponse = response.errorResponse();
        }
    }
});

}

但是在这一行中我得到了编译错误:

 ErrorResponse errorResponse = response.errorResponse();

错误:

Cannot resolve method 'errorResponse()'

2 个答案:

答案 0 :(得分:2)

Kotlin将扩展属性编译为静态方法。这是一个在名为String的文件中扩展StringUtils.kt类的示例:

val String.greeting
  get() = "hello $this"

一个非常简单的方法,当在像"fred".greeting这样的kotlin中调用时,将返回hello fred

如果检查kotlin字节码并在IDE中对其进行反编译,则可以看到结果类似于:

public final class StringUtilsKt {
 @NotNull
 public static final String getGreeting(@NotNull String $this$greeting) {
  Intrinsics.checkParameterIsNotNull($this$greeting, "$this$greeting");
  return "hello " + $this$greeting;
 }
}

StringUtilsKt中的静态方法。这意味着您可以像StringUtilsKt.getGreeting("fred")这样简单地从Java调用它,这将导致相同的输出。

PS:这与扩展功能非常相似。它们也被编译成静态方法,但是名称通常不会改变。

答案 1 :(得分:0)

反编译Kotlin的字节码后,我得到以下信息:

const mapped = objs.map((key, index) => {
  Object.keys(key).map(el => ({
    name: el
  }))
})

因此从Java可以这样调用:

   @NotNull
   public final ErrorResponse getErrorResponse(@NotNull Response $this$errorResponse) {
      Intrinsics.checkParameterIsNotNull($this$errorResponse, "$this$errorResponse");
      ErrorResponse var10000 = ErrorUtils.parseError($this$errorResponse);
      Intrinsics.checkExpressionValueIsNotNull(var10000, "ErrorUtils.parseError(this)");
      return var10000;
   }