Java type reflection

Gosu implements a dynamic type system that is designed to be extended beyond its native objects. A dynamic type system enables Gosu to work with a variety of types. This capability is not the same as items being dynamically typed. Gosu is a statically typed language.

These types include Gosu classes, Java classes, business entity objects, typelists, XML types, SOAP types, and other types. These different types plug into Gosu’s type system similarly to how Gosu business entities connect to the type system.

In almost all ways, Gosu does not differentiate between a Java class instance and a native Gosu object. Both sets of objects are exposed to the language through the same abstract type system. You can use Java types directly in your Gosu code. You can even extend Java classes by writing Gosu types that are subtypes of Java types. Similarly, you can implement or extend Java interfaces from Gosu.

The Gosu language transparently exposes and uses Java classes as Gosu objects through the use of Java BeanInfo objects. Java BeanInfo objects provide analogous information to what a Gosu TypeInfo object provides. Both BeanInfo and TypeInfo objects encapsulate type metadata, including properties and methods. All Java classes have BeanInfo information either explicitly provided with the Java class or dynamically constructed at run time. Gosu examines a Java class’s BeanInfo and determines how to expose this type to Gosu. Because of this behavior, your Gosu code can use the Gosu reflection API with Java types.

In rare cases, you might need to do reflection on the underlying implementation Java class of a Gosu type rather than the Gosu type itself. The Java implementation of the Gosu class is also known as the backing class. For example, suppose you need to inspect each field in the implementing Java class, rather than the Gosu type. You can get the backing class by casting the type to IHasJavaClass as shown in the following example.
uses gw.lang.reflect.IHasJavaClass

// Get the Java backing class

var theType = Policy
var javaClass = (theType.Type as IHasJavaClass).BackingClass

print(javaClass.toString())
print(javaClass.Fields.length) // always zero

// With that class, you can iterate across the native Java fields at run time
for (field in javaClass.Fields index i) {
  print("Field ${i}:\t" + field.Name)
}
This code prints the output similar to the following lines.
class entity.Policy
110
Field 0:	TYPE
Field 1:	ACCOUNT_PROP
Field 2:	ARCHIVEDATE_PROP
Field 3:	ARCHIVEFAILURE_PROP
Field 4:	ARCHIVEFAILUREDETAILS_PROP
Field 5:	ARCHIVEPARTITION_PROP
Field 6:	ARCHIVESCHEMAINFO_PROP
...

The IHasJavaClass interface is implemented only by types that have a Java backing class.