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