Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
179 views
in Technique[技术] by (71.8m points)

java - Preventing the Construction of a "Raw Type" Reference

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...