Type Keys

Many places in the Terra API make use of generics and Java’s Class class for type-safe reflective type handling. This approach generally works quite well.

The Issue

What if you want a registry that registers instances of SomeObject<SomeOtherThing>? Due to type erasure, this is not immediately possible. You cannot access SomeObject<SomeOtherThing>.class, as it simply does not exist at runtime.

A naive solution is to simply use SomeObject.class. This is not ideal for two reasons:

  • It breaks type safety. SomeObject now has no generic type.

  • It will overwrite or be overwritten by anything else that attempts to register any generic type of SomeObject.

The Solution

Terra includes an abstract class called TypeKey to solve this problem. All APIs which accept a Class instance also accept a TypeKey.

Getting a TypeKey

To acquire a TypeKey instance for your type, simply create an anonymous inner class which extends TypeKey with a generic type matching yours. In our SomeObject<SomeOtherThing> example, that would look like:

public static final TypeKey<SomeObject<SomeOtherThing>> SOME_OBJECT_SOME_OTHER_THING_KEY = new TypeKey<>() { };

Note

Notice that the TypeKey is static final. This is to reduce boilerplate by moving the key declaration to the top of the class, and to reduce unneeded instantiation.

Getting a TypeKey from a Class instance

To further reduce boilerplate, you can get a TypeKey directly from a Class instance by using the TypeKey#of(Class) method. This is useful if you need a TypeKey for a non-generic type.

TypeKey<Something> = TypeKey.of(Something.class);