Reflection Kotlin使用反射调用构造函数
对于一个简单的机器语言阅读器,我有许多类AaaInstruction、BbbInstruction、CccInstruction等,它们作为AaaInstruction(v1、v2、v3)调用。其想法是,输入以以下形式给出: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
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),再加上反射,只要做一个简单的语句所能达到的逻辑,那么是的,我认为这很糟糕。仅仅因为它受到支持并不意味着它是一个明智的设计选择。