having a base class A, and the class B and C both extend from A
in A it has function to create a retrofit service, which takes a class type as pram:
protected fun <T> createRemoteService(clazz: Class<T>, baseUrl: String): T {
return Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(createGson()))
.build()
.create(clazz)
}
and in class B and C, the service could be created as (with IBService::class.java or ICService::class.java passed in respectively):
in B:
var remoteServ: IBService
init {
remoteApi = createRemoteService(IBService::class.java, getBaseUrl())
}
and in C:
var remoteServ: ICService
init {
remoteApi = createRemoteService(ICService::class.java, getBaseUrl())
}
it is ok to pass IBService::class.java
as the Class<T>
would like to have a abstract function in base A to return the class type
abstract fun<T> getRemoteServiceClassType() : Class<T>
so it could be done in base A to create the service by getting the class type
remoteServ: Any = createRemoteApi(getRemoteServiceClassType(), getBaseUrl())
and implementation in class B (got error):
override fun<T> getRemoteServiceClassType() : Class<T> {
return IBService::class.java //<=== got compiler error “Type inference
// failed. Expected type mismatch: required Class<T>
// found Class<IBService>
}
interface IBService {
@GET
fun getRemoteData(@Url url: String,
@HeaderMap headers: Map<String, String>,
@QueryMap params: Map<String, String>?):
Call<BResponseData>
}
why cant return IBService::java.class
for the Class<T>
, but passing IBService::class.java
to a function where requires a Class<T>
is ok?
The "correct" signature for getRemoteServiceClassType
is
abstract fun getRemoteServiceClassType() : Class<*>
if any class at all can be returned, or
abstract fun getRemoteServiceClassType() : Class<out SuperType>
if all services should have a common supertype. See https://kotlinlang.org/docs/reference/generics.html for explanation.