Reflection Kotlin使用反射调用构造函数

Reflection Kotlin使用反射调用构造函数,reflection,constructor,kotlin,user-input,invoke,Reflection,Constructor,Kotlin,User Input,Invoke,对于一个简单的机器语言阅读器,我有许多类AaaInstruction、BbbInstruction、CccInstruction等,它们作为AaaInstruction(v1、v2、v3)调用。其想法是,输入以以下形式给出: aaa v1 v2 v3 bbb v1 v2 v3 ccc v1 v2 v3 在主类中,我使用以下代码: var input = Scanner(System.`in`) val instcode = input.next() val cname: String

对于一个简单的机器语言阅读器,我有许多类AaaInstruction、BbbInstruction、CccInstruction等,它们作为AaaInstruction(v1、v2、v3)调用。其想法是,输入以以下形式给出:

aaa v1 v2 v3

bbb v1 v2 v3

ccc v1 v2 v3
在主类中,我使用以下代码:

var input = Scanner(System.`in`)

val instcode = input.next()

val cname: String = instcode.capitalize()+"Instruction"

然后如何调用
cname(v1、v2、v3)

Kotlin中没有内置的枚举类型的方法,也没有类似于Java的
Class.forName()
方法的Kotlin,我认为还没有人专门为Kotlin创建了一个样式库,这意味着需要使用Java反射来获取Kotlin类,这听起来非常糟糕。在我看来,这一点一开始就不太好——将外部输入映射到类名听起来像是一场安全噩梦

考虑到您的用例,有几种方法可以使用

首先,您可以实现一个合适的工厂(一个大的switch语句就可以了,一个构造函数映射会稍微简洁一些),而不是试图从操作码中构建您想要的构造函数的名称。我知道这可能是你试图避免的,但根据我的经验,你在避免它时遇到的问题比你正在避免的问题要大


第二,如果您死心塌地地想在某个地方使用反射,那么可以将所有操作码实现创建为单个元类的嵌套类,然后使用
KClass
nestedClasses
属性遍历这些类,并找到其
simpleName
属性与您要查找的操作码匹配的操作码。不过这很难看。您还需要包括Kotlin的反射运行时JAR,默认情况下不包括它;请参阅。

没有理由认为使用Java反射获取Kotlin类会很糟糕。Kotlin支持与Java反射的双向互操作,在两者之间使用简单的API。如果您需要使用两次互操作(Kotlin->Java反射,然后在找到要查找的类后的某个时候使用Java->Kotlin),再加上反射,只要做一个简单的
语句所能达到的逻辑,那么是的,我认为这很糟糕。仅仅因为它受到支持并不意味着它是一个明智的设计选择。