我跟随these instructions创建了一个简单的服务定位器,该定位器适用于Kotlin,并针对我的问题进行了简化:
object ServiceLocator {
@JvmStatic
fun getService(serviceName: String): Any {
val service = lookupService(serviceName)
if (service != null) {
return service
}
throw UnknownServiceException()
}
private fun lookupService(serviceName: String): Any? {
if (serviceName.equals("MyService")) {
return MyService()
}
return null
}
}
我可以如下使用它:
val myService = ServiceLocator.getService("MyService") as IMyService
我遇到的问题是myService
的类型为Any
。如果getService
返回实际类型,我会更喜欢。理想情况下,我想这样使用它:
val myService = ServiceLocator.getService<IMyService>()
或者,如果不可能的话,可以这样做:
val myService = ServiceLocator.getService(IMyService::class)
我不知道如何使通用类型参数起作用。这是我尝试过的:
@JvmStatic
fun <T> getService(): T {
val service = lookupService<T>()
if (service != null) {
return service
}
throw UnknownServiceException()
}
private fun <T> lookupService(): T? {
if (T::class == IMyService::class) {
return MyService()
}
return null
}
编译器抱怨两件事:
T::class
上,它抱怨“不能使用'T'作为化类型参数。请改用类。” return MyService()
上,显示“类型不匹配。是否要求:T?找到了:MyService” 答案 0 :(得分:2)
要在运行时访问类型T
,而不必传入类(例如ServiceLocator.getService(IMyService::class)
),则必须使用reified type parameter。暗示这意味着您必须将方法更改为inline functions。这样,您可以将代码更新为以下内容:
@JvmStatic
inline fun <reified T> getService(): T {
val service = lookupService<T>()
if (service != null) {
return service
}
throw UnknownServiceException()
}
inline fun <reified T> lookupService(): T? {
if (T::class == IMyService::class) {
return MyService() as T
}
return null
}