Retrofit.create()无类引用参数时如何确定返回类型?
关于Retrofit中reified泛型create()函数的疑问
我在应用中使用Hilt模块提供Retrofit API,相关代码如下:
Hilt模块代码
@Module @InstallIn(SingletonComponent::class) object NetworkDataModule { @Provides @Singleton fun provideOkHttpClient(): OkHttpClient { return OkHttpClient.Builder() .addInterceptor( HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY } ) .build() } @Provides @Singleton fun provideMyApi(client: OkHttpClient): MyApi { return Retrofit.Builder() .baseUrl(MyApi.BASE_URL) .addConverterFactory(MoshiConverterFactory.create()) .client(client) .build() .create() } }
API接口定义
interface MyApi { @GET("search") suspend fun search(): searchDto companion object { const val BASE_URL = "https://myapi.com/" } }
我的疑问是:Retrofit的create()扩展函数未传入MyApi接口的相关信息,为何能返回对应的实例?该函数的实现为:
inline fun <reified T> Retrofit.create(): T = create(T::class.java)
为何无需指定泛型类型T,create(T::class.java)就能返回MyApi实例?我的Retrofit版本为2.9.0。
解答
这是Kotlin中reified泛型的特性结合返回值类型推导共同作用的结果:
reified泛型解决类型擦除问题
普通泛型在编译阶段会被类型擦除,无法直接获取T::class.java这类具体类型信息。但用reified修饰的泛型,会在编译时保留实际类型的元数据,允许在函数内部直接访问该类型的类对象。返回值类型自动推导泛型参数
在provideMyApi函数中,返回值明确声明为MyApi。当调用retrofit.create()时,Kotlin编译器会根据函数的返回值类型,自动推导出泛型参数T的具体类型就是MyApi——相当于编译器帮你补全了retrofit.create<MyApi>()的调用。
结合这两点,create()函数就能通过MyApi::class.java拿到接口的类对象,传给Retrofit原生的create(Class<T>)方法,最终动态生成MyApi的实现实例。
内容的提问来源于stack exchange,提问作者Squti
相关产品推荐
相关产品推荐

