Jackson在反序列化是有两个可配置的特性:INTERN_FIELD_NAMES和CANONICALIZE_FIELD_NAMES。
/**
* Feature that determines whether JSON object field names are
* to be canonicalized using {@link String#intern} or not:
* if enabled, all field names will be intern()ed (and caller
* can count on this being true for all such names); if disabled,
* no intern()ing is done. There may still be basic
* canonicalization (that is, same String will be used to represent
* all identical object property names for a single document).
*
* Note: this setting only has effect if
* {@link #CANONICALIZE_FIELD_NAMES} is true -- otherwise no
* canonicalization of any sort is done.
*
* This setting is enabled by default.
*/
INTERN_FIELD_NAMES(true),
/**
* Feature that determines whether JSON object field names are
* to be canonicalized (details of how canonicalization is done
* then further specified by
* {@link #INTERN_FIELD_NAMES}).
*
* This setting is enabled by default.
*/
CANONICALIZE_FIELD_NAMES(true)
根据注释可以看出来,这两个特性的作用是决定是否要规范化json串的key(即调用key的intern方法),并且只有在CANONICALIZE_FIELD_NAMES生效时,INTERN_FIELD_NAMES才会生效。
在获取json串的下一个token时,即ReaderBasedJsonParser的nextToken()方法中,解析了key的名称,代码如下:
boolean inObject = _parsingContext.inObject();
if (inObject) {
// First, field name itself:
String name = _parseName(i);//解析key的名称
_parsingContext.setCurrentName(name);
_currToken = JsonToken.FIELD_NAME;
i = _skipWS();
if (i != INT_COLON) {
_reportUnexpectedChar(i, "was expecting a colon to separate field name and value");
}
i = _skipWS();
}
_symbols.findSymbol(buf, start, len, hash),看一下findSymbol的实现会先后看到下面两个实现逻辑
逻辑1:
if (!_canonicalize) { // [JACKSON-259]
return new String(buffer, start, len);
}
逻辑2:
String newSymbol = new String(buffer, start, len);
if (_intern) {
newSymbol = InternCache.instance.intern(newSymbol);
}
在ObjectMapper的readValue(String content, Class<T> valueType)方法中,先初始化了jsonParser(在JsonFactory的createParser方法中),
protected JsonParser _createParser(Reader r, IOContext ctxt)
throws IOException, JsonParseException
{
return new ReaderBasedJsonParser(ctxt, _parserFeatures, r, _objectCodec,
_rootCharSymbols.makeChild(isEnabled(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES),
isEnabled(JsonFactory.Feature.INTERN_FIELD_NAMES)));
}
它实现了ConcurrentHashMap,为的是防止多次调用同一个字符串的intern方法。