我跟着these instructions创建一个简单的服务定位器,适用于科特林和简化更对我的问题的目的:
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”要访问的类型,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
}