Java 如何按名称实例化参数化类型类

Java 如何按名称实例化参数化类型类,java,generics,kotlin,parameterization,Java,Generics,Kotlin,Parameterization,以下示例: 我有一种可以“启动”任何车辆的服务 interface VehicleStarterService<T: Vehicle> { fun <T : Vehicle> start(vehicle: Class<T>): String { return vehicle.start } } interface VehicleStarterService{ 有趣的开始(车辆:类别):字符串{ 返回车辆。启动 } } 我想启动一个

以下示例:

我有一种可以“启动”任何车辆的服务

interface VehicleStarterService<T: Vehicle> {
   fun <T : Vehicle> start(vehicle: Class<T>): String {
       return vehicle.start
   }
}
interface VehicleStarterService{
有趣的开始(车辆:类别):字符串{
返回车辆。启动
}
}
我想启动一个车辆类型的名称,如“车”,这将需要我创建一个VehicleStarterService;然而,我似乎找不到一种方法来实例化一个带有按名称实例化的类的接口

我想做以下事情(但不能):

val cls=“汽车”
val kClass=Class.forName(cls).kotlin
val服务=VehicleStarterService()
服务启动
我最终不得不做以下事情(为我需要的每个参数化类型创建一个服务):

class汽车起动服务:车辆起动服务{
fun execute():字符串{
返回开始(User::class.java)
}
}

有没有办法用这种方式实例化一个参数化的类?

目前还不清楚这是否足以满足您的情况,但也许您可以根据如下字符串匹配该类

val cls = "Car"
val service: VehicleStarterService<out Vehicle>? = when (cls) {
    "Car"  -> object : VehicleStarterService<Car> {}
    "Boat" -> object : VehicleStarterService<Boat> {}
    "Plane" -> object : VehicleStarterService<Plane> {}
    else   -> null
}
service?.start(...
val cls=“汽车”
增值税服务:车辆增值税服务?=何时(cls){
“Car”->对象:VehicleStarterService{}
“船”->对象:VehicleStarterService{}
“平面”->对象:VehicleStarterService{}
else->null
}
服务?启动(。。。
编辑:hashmap注册表思想允许一些扩展性

val serviceRegistry = HashMap<String, VehicleStarterService<out Vehicle>>()
    .apply {
        //default services
        this["Car"] = object : VehicleStarterService<Car> {}
        this["Boat"] = object: VehicleStarterService<Boat> {}
    }
.
.
.
//Adding entry
serviceRegistry["Plane"] = object: VehicleStarterService<Plane> {}
.
.
.
//Fetching entry
val cls = "Car"
val service = serviceRegistry[cls]

service?.start(...
val serviceRegistry=HashMap()
.申请{
//默认服务
this[“Car”]=对象:VehicleStarterService{}
此[“船”]=对象:VehicleStarterService{}
}
.
.
.
//添加条目
serviceRegistry[“Plane”]=对象:VehicleStarterService{}
.
.
.
//获取条目
val cls=“汽车”
val service=serviceRegistry[cls]
服务?启动(。。。

我真的看不出您的问题。请注意,泛型类型信息在运行时会被删除(至少对于您显然正在使用的JVM变体而言)。因此,您使用哪种泛型服务基本上无关紧要。 您也可以只使用
VehicleStarterService
,它将启动您的所有车辆。如果出于任何原因您需要调用特定(其他!)函数,您仍然需要检查/转换为您的实际类型…因此,我认为尝试获得通用类型接口没有任何好处

已经说过,仍然有方法可以做到这一点…(再次注意:这并不重要…泛型类型信息在运行时被擦除…)

现在,对于我的测试,我使用以下输入方法:

fun startAllTheVehicles(vararg vehicleTypes: String) {
  startAllTheVehicles(*vehicleTypes.map { Class.forName(it) }
                                   .map { it as Class<out Vehicle> }
                                   .toTypedArray())
}
上述输入函数使用一个服务调用的示例方法来启动所有车辆:

fun <T : Vehicle> startAllTheVehicles(vararg vehicleTypes: Class<out T>) {
  val service = object : VehicleStarterService {}
  vehicleTypes.forEach { service.start(it) }
}
fun <T : Vehicle> startAllTheVehicles(vararg vehicleTypes: Class<out T>) {
  // actually it doesn't really matter which type we use...
  val service = object : VehicleStarterService<Vehicle> {} // you could even use T instead of Vehicle
  vehicleTypes.forEach { service.start(it) }
}
entry函数使用一个服务调用的示例方法来启动所有车辆:

fun <T : Vehicle> startAllTheVehicles(vararg vehicleTypes: Class<out T>) {
  val service = object : VehicleStarterService {}
  vehicleTypes.forEach { service.start(it) }
}
fun <T : Vehicle> startAllTheVehicles(vararg vehicleTypes: Class<out T>) {
  // actually it doesn't really matter which type we use...
  val service = object : VehicleStarterService<Vehicle> {} // you could even use T instead of Vehicle
  vehicleTypes.forEach { service.start(it) }
}

用一个实际上不是
Vehicle
的类型调用它,会在接口的
start
-函数中给你一个
ClassCastException

我会说不是。类型实例化必须在编译时发生,但字符串中的类型名只有在运行时才知道。根据
start
真正应该做什么,可能是generics是不必要的,所有车辆的通用接口加上特定车辆的类对象就足够了。您要做的是等效于原始类型,所以只需使用原始类型。我希望能够避免添加这样的匹配器(要求其他人更改基础“库”类)但是,是的,这绝对是一个选项!我在第二个想法中编辑,使用hashmap作为注册表,以便其他人可以添加他们自己的服务并获取这些服务
interface VehicleStarterService<T: Vehicle> {
  fun start(vehicleType: Class<out T>) = vehicleType.newInstance().start
}
fun <T : Vehicle> startAllTheVehicles(vararg vehicleTypes: Class<out T>) {
  // actually it doesn't really matter which type we use...
  val service = object : VehicleStarterService<Vehicle> {} // you could even use T instead of Vehicle
  vehicleTypes.forEach { service.start(it) }
}
startAllTheVehicles("Car", "Truck")