Retrieving methods by using reflection

You can use reflection to find all the methods that a class provides and to get information about individual methods. You can even call methods by name (given a String for the method name) and pass a list of parameters as object values. You can call a method using the method’s CallHandler property, which contains a handleCall method.

Because of performance implications and the inability to find errors at compile time, only use reflection if there is no other way to do what you need.

To examine how reflection provides information about class methods, paste the following code into the Gosu Scratchpad.

var object = "This is a string"
var methodNames = ""
var methods = (typeof object).TypeInfo.Methods

for (method in methods) {
  methodNames = methodNames + method.Name + "  "
}

print(methodNames)

This code prints lines similar to the following output, which is truncated for brevity.

wait()  wait( long, int )  wait( long )  hashCode()  getClass()  equals( java.lang.Object )
toString()  notify()  notifyAll()  @itype()  compareTo( java.lang.String )  charAt( int ) 
length()  subSequence( int, int )  indexOf( java.lang.String, int )  indexOf( java.lang.String )
indexOf( int )  indexOf( int, int )  codePointAt( int )  codePointBefore( int )

The following example gets a method by name and then calls that method. This example uses the String class and its compareTo method, which returns0, 1, or-1. Paste the following code into the Gosu Scratchpad.

// Initialize test data
var objectText = "a"
var argumentText = "b"

// Get the list of methods
var methodInfos = String.Type.TypeInfo.Methods

// Find a specific method by name.
// More than one method signature may exist for the same name, so the return type is an array
// of results with each method having different argument numbers or types
var compareToMethodName = methodInfos.firstWhere( \ elt -> elt.DisplayName == "compareTo")
if (compareToMethodName == null) { throw "Could not find method by name" }

print("Full method name is: " + compareToMethodName.Name)
print("Number of parameters is: " + compareToMethodName.Parameters.length)
print("Name of first parameter is: " + compareToMethodName.Parameters[0].DisplayName)
print("Type of first parameter is " + compareToMethodName.Parameters[0].OwnersType.toString())

var res = compareToMethodName.CallHandler.handleCall( objectText, { argumentText } )
print("Call compareTo() using reflection: " + res)

var res2 = objectText.compareTo(argumentText)
print("Call compareTo() the normal way (with static typing): " + res2)

The code prints the following output.

Full method name is: compareTo( java.lang.String )
Number of parameters is: 1
Name of first parameter is: String
Call compareTo() using reflection: -1
Call compareTo() the normal way (with static typing): -1