java - 无法将具有类型参数的 Java 类重写为 Kotlin
问题描述
我以为我对 Kotlin 的in
,out
和*
修饰符有很好的理解,但我无法将一个类从 Java 重写为 Kotlin。也许有人可以帮助我。在我的应用程序中,我正在使用改造,并且在我的所有项目中,我都有这个 ApiResponseValidatorJava 类,它负责验证 API 响应模型,例如 Customer。用 Kotlin 编写的这个类看起来如何?
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.HashMap;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
public class ApiResponseValidatorJava extends Converter.Factory {
private HashMap<Type, ModelValidator> validators = new HashMap();
public ApiResponseValidatorJava(ModelValidator... validators) {
for (ModelValidator v : validators) {
this.validators.put(v.getModelType(), v);
}
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(final Type type, Annotation[] annotations, Retrofit retrofit) {
final Converter<ResponseBody, Object> mainConverter = retrofit.nextResponseBodyConverter(this, type, annotations);
return new Converter<ResponseBody, Object>() {
@Override
public Object convert(ResponseBody value) throws IOException {
Object apiResponseModel = mainConverter.convert(value);
if (validators.containsKey(type)) {
validators.get(type).validate(apiResponseModel);
}
return apiResponseModel;
}
};
}
}
import java.lang.reflect.Type
interface ModelValidator<T> {
fun getModelType(): Type
fun validate(data: T)
}
import retrofit2.Call
import retrofit2.http.*
interface Api {
@GET("api/session/customer")
fun getCustomer(): Call<Customer>
}
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class Customer(
@Json(name = "id")
val id: String,
@Json(name = "phone")
val phone: String
)
class CustomerResponseValidator : ModelValidator<Customer> {
override fun getModelType() = Customer::class.java
override fun validate(customer: Customer) {
if (!customer.phone.startsWith("+212")) {
throw IllegalAccessException("Phone doesn't start with +212")
}
}
}
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
private fun buildRetrofit(): Api {
val apiResponseValidator = ApiResponseValidatorJava(
CustomerResponseValidator()
)
return Retrofit.Builder()
.baseUrl("https://example.com/")
.client(OkHttpClient.Builder().build())
.addConverterFactory(apiResponseValidator)
.addConverterFactory(MoshiConverterFactory.create())
.build()
.create(Api::class.java)
}
}
// gradle dependecies
implementation group: 'com.squareup.retrofit2', name: 'retrofit', version: '2.6.2'
implementation group: 'com.squareup.retrofit2', name: 'converter-moshi', version: '2.6.2'
implementation group: 'com.squareup.moshi', name: 'moshi', version: '1.8.0'
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.8.0"
解决方案
由于您希望接收ModelValidator
每个泛型类型的输入 a,您可以使用ModelValidator<out Any?>
.
你可以使用这样的东西:
class ApiResponseValidatorJava(vararg validators: ModelValidator<out Any?>) : Converter.Factory() {
private val validators = mutableMapOf<Type, ModelValidator<Any?>>().apply {
validators.forEach {
@Suppress("UNCHECKED_CAST")
this[it.getModelType()] = it as ModelValidator<Any?>
}
}
override fun responseBodyConverter(
type: Type,
annotations: Array<Annotation>,
retrofit: Retrofit
): Converter<ResponseBody, *> {
val mainConverter = retrofit.nextResponseBodyConverter<Any?>(this, type, annotations)
return Converter<ResponseBody, Any?> { value ->
mainConverter.convert(value).also { apiResponseModel ->
validators[type]?.validate(apiResponseModel)
}
}
}
}
推荐阅读
- php - 为什么我在循环中填充数组变量时为空?
- python - steamworks InitiateGameConnection() 中是否有类似的 python 函数?
- r - 为什么从 RStudio 运行脚本时遇到 R 致命错误
- mount - 使用 mtpmount 和 dokany 进行 MTP 热拔出 - 是否严格要求卸载?
- postgresql - 使用 Postgresql JSON 字段作为映射的实体的 Spring Boot JPA 投影
- matlab - MATLAB从VTK文件中读取数据使用
- linux - 不一致的 SSL 证书 // Linux 服务器
- haskell - 如何推断递归函数的类型?
- c# - C#遍历文件结构时如何判断所有线程或任务何时完成
- .net - RPA 中支持记录器、执行功能等特性/功能的底层技术是什么