此文诞生于对 FastJSON 组件中 com.alibaba.fastjson.parser.Feature 类的学习。
一个组件中可能有很多特性需要支持,但在实际应用中却需要根据使用组件之人的喜好进行配置。比如在 FastJSON 组件中就有以下特性可由使用者自主选择:
- AutoCloseSource, 自动关闭源
- AllowComment, 支持注释
- AllowUnQuotedFieldNames, 支持未引用的字段名
- AllowSingleQuotes, 支持单引号
- InternFieldNames,
- AllowISO8601DateFormat, 支持ISO8601格式的日期
- AllowArbitraryCommas, 支持任意多个逗号
- UseBigDecimal, 使用大数
- IgnoreNotMatch, 忽略不匹配的
- SortFeidFastMatch,
- DisableASM,
- DisableCircularReferenceDetect, 关闭循环引用发现
- InitStringFieldAsEmpty, 初始化字符串字段为 空字符串
- SupportArrayToBean, 支持由数组转换成Bean对象
- OrderedField, 按字段排序
- DisableSpecialKeyDetect,
- UseObjectArray,
- SupportNonPublicField, 支持非 public 字段
- IgnoreAutoType, 忽略自动类型
- DisableFieldSmartMatch, 关闭字段的智能匹配特性
- SupportAutoType, 支持自动类型
- NonStringKeyAsString,
- CustomMapDeserializer,
以上有23个特性之多,每一个特性有两种状态(支持、不支持),每个特性之间互不影响。可以把每个特性对应一个“开关”,而计算机最喜欢处理的就是“开关”(0、1)。在Java语言中int类型用32位二进制表示,每一位二进制可以当成一个开关。如此一来,以上23个特性使用一个int类型进行表示已是绰绰有余,FastJSON 就是这样做的。
以上23个特性对应于 com.alibaba.fastjson.parser.Feature (枚举类型)中的23个枚举常量。Feature 为每个枚举常量定义了一个int 类型的变量 mask ,用于说明它的“开关”在 int 类型上对应的二进制位。
public final int mask;
Feature(){
mask = (1 << ordinal());
}
判断是否支持某特性
public static boolean isEnabled(int features, Feature feature) {
return (features & feature.mask) != 0;
}
把一个特性加入配置或从配置中删除
public static int config(int features, Feature feature, boolean state) {
if (state) {
features |= feature.mask;
} else {
features &= ~feature.mask;
}
return features;
}
把需要支持的特性数组(Feature[])转换成配置
public static int of(Feature[] features) {
if (features == null) {
return 0;
}
int value = 0;
for (Feature feature: features) {
value |= feature.mask;
}
return value;
}
另外多说一句,FastJSON 在把JSON格式的字符串转换成Java对象时(反序列化),默认使用的特性如下:
public static int DEFAULT_PARSER_FEATURE;
static {
int features = 0;
features |= Feature.AutoCloseSource.getMask();
features |= Feature.InternFieldNames.getMask();
features |= Feature.UseBigDecimal.getMask();
features |= Feature.AllowUnQuotedFieldNames.getMask();
features |= Feature.AllowSingleQuotes.getMask();
features |= Feature.AllowArbitraryCommas.getMask();
features |= Feature.SortFeidFastMatch.getMask();
features |= Feature.IgnoreNotMatch.getMask();
DEFAULT_PARSER_FEATURE = features;
}
网友评论