l.B
l.B

Reputation: 11

Kotlin invoke constructor using reflection

For a simple machine language reader, I have a number of classes AaaInstruction, BbbInstruction, CccInstruction, etc. which are invoked as aaaInstruction(v1, v2, v3). The idea is that the input is given in the form:

aaa v1 v2 v3

bbb v1 v2 v3

ccc v1 v2 v3

In the main class I use the following code:

var input = Scanner(System.`in`)

val instcode = input.next()

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

How can I then invoke cname(v1,v2,v3)?

Upvotes: 1

Views: 1386

Answers (1)

Logan Pickup
Logan Pickup

Reputation: 2374

There is no built-in way to enumerate types in Kotlin, there isn't a Kotlin analogue to Java's Class.forName() method, and I do not think anyone has made a Reflections-style library specifically for Kotlin yet, which means you would need to use Java reflection to get the Kotlin classes, and that's starting to sound pretty terrible. It's not great in the first place in my opinion - having an external input map to a class name sounds like a security nightmare.

Given your use case, there are a couple of approaches you could use.

First, you could implement a proper factory (a big switch statement would do, a map of constructors would be slightly more concise) instead of trying to build the name of the constructor you want from the opcode. I know that's probably what you're trying to avoid, but in my experience the problems you will run into avoiding it are bigger than the ones you are avoiding.

Second, if you are dead-set on using reflection somewhere, you can create all the opcode implementations as nested classes of a single meta-class, which you can then walk through using the nestedClasses property of KClass, and find the one whose simpleName property matches the opcode you're looking for. This is pretty ugly, though. You'll also need to include Kotlin's reflection runtime JAR, which is not included by default; see http://kotlinlang.org/docs/reference/reflection.html.

Upvotes: 1

Related Questions