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.
SomeObjectnow 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);