The Jackson Core library contains the TypeReference abstract class.
This class implements Comparable. The JavaDoc explains why:
It uses a...
...bogus implementation of Comparable (any such generic interface would do, as long as it forces a method with generic type to be implemented), to ensure that a Type argument is indeed given.
and:
compareTo(): The only reason we define this method (and require implementation of Comparable) is to prevent constructing a reference without type information.
An example of using TypeReference with type information (Map<String, Object>):
String json = "{ \"some_key\": 123 }";
ObjectMapper objectMapper = new ObjectMapper();
TypeReference<Map<String, Integer>> typeReference = new TypeReference<>(){};
Map<String, Integer> map = objectMapper.readValue(json, typeReference);
(The class is abstract, but it contains an implementation of compareTo() - so I don't need to provide one.)
The above technique does not stop me from constructing a reference without type information. The following compiles successfully (although the end result is not useful):
// bad idea - just for illustration:
TypeReference typeReference2 = new TypeReference() {};
What am I missing about the use of Comparable here? It does not prevent code compilation. I don't see how it could.
Compiler warnings are a different matter - I'm wondering specifically about the "prevention" claim.
Background Notes:
If I try to use my raw type typeReference2, it will throw a runtime exception, because of the following check in the constructor:
Type superClass = getClass().getGenericSuperclass();
if (superClass instanceof Class<?>) { // sanity check, should never happen
throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information");
}
The Javadoc for the class refers to an article which discusses the above runtime technique. It seems that a comment in that article prompted the inclusion of Comparable in Jackson's TypeReference class:
Rather than check for a type parameter in the constructor, you can make it a syntax error to leave out:
public abstract TypeReference<R> implements Comparable<TypeReference<R>> { // ... public int compareTo(TypeReference<R> o) { // Need a real implementation. // Only saying "return 0" for illustration. return 0; } }Now this is legal:
new TypeReference<Object>() { };But this is a syntax error for not implementing Comparable:
new TypeReference() { };
I do not see this as a syntax error for TypeReference. It compiles OK, and we've been given an implementation in the class already.