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.
question from:
https://stackoverflow.com/questions/65944812/preventing-the-construction-of-a-raw-type-reference