Kotlin 中具有泛型类型参数的简单服务定位器

Simple service locator with generic type parameters in Kotlin

我按照 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
}

编译器抱怨两件事:

  1. T::class 上,它抱怨 "Cannot use 'T' as reified type parameter. Use a class instead."
  2. return MyService() 上,显示 "Type mismatch. Required: T? Found: MyService"

要在运行时访问类型 T,而不必在(例如 ServiceLocator.getService(IMyService::class))中传递 class,您必须使用 reified type parameter. Implicitly this means you have to change your methods to be 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
}