Converted java class file to kotlin makes compilation error

I have a java class file that works great, but if I convert it to Kotlin it creates some problems. Here is the Java version

 public class CallbackWrapper<T> implements Callback<T> {
   private Wrapper<T> wrapper;

   public CallbackWrapper(Wrapper<T> wrapper) {
      this.wrapper = wrapper;
   }

   public void onFailure(Call<T> call, Throwable t) {
      wrapper.onResult(t, null);
   }

   public void onResponse(Call<T> call, Response<T> response) {
      wrapper.onResult(null, response);
   }

   public interface Wrapper<T> {
      void onResult(@Nullable Throwable t, @Nullable Response<T> response);
   }
}

      

And this is how I use this class with no problem ...

request.enqueue(CallbackWrapper<RegisterResponse> { throwable, response ->
     response?.let { callBack.onResponse(response.body() ?: RegisterResponse()) }
     throwable?.let { callBack.onFailed(throwable.message!!) }
 })

      

And here is the Kotlin version after conversion

class CallbackWrapper<T>(private val wrapper: CallbackWrapper.Wrapper<T>) : Callback<T> {

    override fun onFailure(call: Call<T>, t: Throwable) {
        wrapper.onResult(t, null)
    }

    override fun onResponse(call: Call<T>, response: Response<T>) {
        wrapper.onResult(null, response)
    }

    interface Wrapper<T> {
        fun onResult(t: Throwable?, response: Response<T>?)
    }
}

      

The problem is, after converting to Kotlin, the block of code where I am using this class does not work. I don't understand what is the difference between them.

Here is the compilation error log

Error:(17, 63) Type mismatch: inferred type is (???, ???) -> [ERROR :<ERROR FUNCTION RETURN TYPE>] but CallbackWrapper.Wrapper<RegisterResponse> was expected
Error:(17, 65) Cannot infer a type for this parameter. Please specify it explicitly.
Error:(17, 76) Cannot infer a type for this parameter. Please specify it explicitly.

      

+3


source to share


1 answer


You have two problems with your code as far as I can tell.

First, Kotlin does not allow lambdas to be used to implement Kotlin functional interfaces, so your lambda will not work (this allows Java functional interfaces to be implemented because Java does not have proper function types). Therefore, in order to call your code unchanged, you want to use object notation instead:

request.enqueue(CallbackWrapper<RegisterResponse>(object : CallbackWrapper.Wrapper<RegisterResponse> {
        override fun onResult(throwable: Throwable?, response: Response<RegisterResponse>?) {
            response?.let { callBack.onResponse(response.body() ?: RegisterResponse()) }
            throwable?.let { callBack.onFailure(throwable.message!!) }
        }
    }))

      

You can declare your class CallbackWrapper

differently if you prefer using lambdas:

typealias Wrapper<T> = (t: Throwable?, response: Response<T>?) -> Unit
class OtherCallbackWrapper<T>(val wrapper: Wrapper<T>) : Callback<T> {
    override fun onFailure(call: Call<T>, t: Throwable) = wrapper.invoke(t, null)
    override fun onResponse(call: Call<T>, response: Response<T>) = wrapper.invoke(null, response)
}

      



So the part has but CallbackWrapper.Wrapper<RegisterResponse> was expected

taken care.

However, that still won't work, which leads us to the first half of the error message inferred type is (???, ???) -> [ERROR :<ERROR FUNCTION RETURN TYPE>]

. This is basically the type of inference that fails. The call callBack

doesn't quite match the interface callBack

that CallbackWrapper implies, which I suppose may have something to do with it.

EDIT:

Added an answer to your question "Retrofitting" with a shorter solution.

+3


source







All Articles