大家好,又见面了,我是你们的朋友全栈君。
JSON(JavaScript Object Notation的首字母缩写)是一种轻量级数据交换格式,最常用于客户端 – 服务器通信。它既易于读/写,又与语言无关。JSON值可以是另一个JSON 对象,数组,数字,字符串,布尔值(true / false)或null。也是后端开发中经常要接触的一个一个类,将要数据封装成json然后传递给前端。 只要我们导入如下maven依赖即可使用由阿里巴巴发布的JSON工具类。
代码语言:javascript复制//版本可选择
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
下面将对JSONObject 的源码进行解析。
JSONObject 的接口
代码语言:javascript复制public class JSONObject extends JSON
implements Map<String, Object>, Cloneable, Serializable, InvocationHandler
1.JSONObject继承自JSON ,JSON是Fastjson的一个主要类,常常需要调用JSON的两个方法:toJSONString(Object)【将指定的对象序列化成Json表示形式】和parseObject(String, Class)【将json反序列化为指定的Class模式】 2.JSONObject实现了Map<String, Object>,可见JSONObject是一个Map类型的数据结构,Map接口提供了很多操作map的方法,常用的增删改查。 3.JSONObject还实现了Cloneable, Serializable, InvocationHandler,说明JSONObject支持拷贝(并且JSONObject重写了clone方法),支持序列化与反序列化,InvocationHandler是通过一个代理实例零调用处理程序实现的接口,即标记使用Java动态代理机制。JDK文档指示:每个代理实例都有一个相关的调用处理程序。当一个方法是在一个代理实例调用,调用的方法进行编码并派遣其调用处理程序的invoke方法。
JSONObject 的字段
代码语言:javascript复制 private static final long serialVersionUID = 1L;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
private final Map<String, Object> map;
JSONObject有三个字段, 1.serialVersionUID(版本标识)是 Java 为每个序列化类产生的版本标识,可用来保证在反序列时,发送方发送的和接受方接收的是可兼容的对象。如果接收方接收的类的 serialVersionUID 与发送方发送的 serialVersionUID 不一致,进行反序列时会抛出 InvalidClassException。序列化的类可显式声明 serialVersionUID 的值,如下:
代码语言:javascript复制ANY-ACCESS-MODIFIER static final long serialVersionUID = 1L;
当显式定义 serialVersionUID 的值时,Java 根据类的多个方面(具体可参考 Java 序列化规范)动态生成一个默认的 serialVersionUID 。尽管这样,还是建议你在每一个序列化的类中显式指定 serialVersionUID 的值,因为不同的 jdk 编译很可能会生成不同serialVersionUID 默认值,进而导致在反序列化时抛出 InvalidClassExceptions 异常。所以,为了保证在不同的 jdk 编译实现中,其 serialVersionUID 的值也一致,可序列化的类必须显式指定 serialVersionUID 的值。另外,serialVersionUID 的修饰符最好是 private,因为 serialVersionUID 不能被继承,所以建议使用 private 修饰 serialVersionUID。【以上出自java.io.Serializable doc 文档】 2.DEFAULT_INITIAL_CAPACITY 默认初始容量,大小为16 3.map,用于存储的的容器,JSONObject常用的两种类型,LinkedHashMap(有序)和HashMap类型。默认初始大小为16。
JSONObject的构造器
最重要的构造器是public JSONObject(int initialCapacity, boolean ordered),其他构造器都直接调用此构造器。initialCapacity为初始容量,ordered为map是否有序
代码语言:javascript复制 //构造容量为16个单位的HashMap作为JSONObject
public JSONObject(){
//调用public JSONObject(int initialCapacity, boolean ordered)
this(DEFAULT_INITIAL_CAPACITY, false);
}
//构造自定义Map<String, Object> 容器类型的JSONObject
public JSONObject(Map<String, Object> map){
if (map == null) {
throw new IllegalArgumentException("map is null.");
}
this.map = map;
}
//构造容量为16个单位JSONObject,可选择器容器是否有序:LinkedHashMap(true)、HashMap(false)
public JSONObject(boolean ordered){
this(DEFAULT_INITIAL_CAPACITY, ordered);
}
//构造自定义初始大小的HashMap类型的JSONObject
public JSONObject(int initialCapacity){
this(initialCapacity, false);
}
public JSONObject(int initialCapacity, boolean ordered){
if (ordered) {
map = new LinkedHashMap<String, Object>(initialCapacity);
} else {
map = new HashMap<String, Object>(initialCapacity);
}
}
使用示例:
代码语言:javascript复制 //构造容量为16个单位的HashMap作为JSONObject
JSONObject jsonObject = new JSONObject();
//构造容量为16个单位JSONObject,可选择器容器是否有序:LinkedHashMap(true)、HashMap(false)
JSONObject jsonObject1 = new JSONObject(true);
//构造自定义Map<String, Object> 容器类型的JSONObject
Map<String,Object> map = new ConcurrentHashMap<>(16);
JSONObject jsonObject2 = new JSONObject(map);
//自定义
JSONObject jsonObject3 = new JSONObject(32, false);
JSONObject的方法
JSONObject类里共有个方法,继承JSON但未重写的方法下面暂不列出。
方法 | 作用 |
---|---|
public int size() | map的key-value个数 |
public boolean isEmpty() | 判断是否为没有键值对的JSONObject |
public boolean containsKey(Object key) | 判断JSONObject是否包含此key值 |
public boolean containsValue(Object value) | 判断JSONObject是否包含此value值 |
public Object get(Object key) | 通过key获取对应的key-value对象 |
public JSONObject getJSONObject(String key) | 根据key获取JSONObject 对象 |
public JSONArray getJSONArray(String key) | 根据key获取JSONArray |
public T getObject(String key, Class clazz) | 获取指定的类型的对象 |
public T getObject(String key, Type type) | 获取指定的类型的对象 |
public T getObject(String key, TypeReference typeReference) | 获取指定的类型的对象 |
public Boolean getBoolean(String key) | 通过String key取获取Boolean的value |
public byte[] getBytes(String key) | 通过String key取获取byte[] 的value |
public boolean getBooleanValue(String key) | 通过String key取获取boolean 的value |
public Byte getByte(String key) | 通过String key取获取Byte的value |
public byte getByteValue(String key) | 通过String key取获取byte 的value |
public Short getShort(String key) | 通过String key取获取Short的value |
public short getShortValue(String key) | 通过String key取获取short 的value |
public Integer getInteger(String key) | 通过String key取获取Integer 的value |
public int getIntValue(String key) | 通过String key取获取int 的value |
public Long getLong(String key) | 通过String key取获取Long 的value |
public long getLongValue(String key) | 通过String key取获取long 的value |
public Float getFloat(String key) | 通过String key取获取Float 的value |
public float getFloatValue(String key) | 通过String key取获取float 的value |
public Double getDouble(String key) | 通过String key取获取Double 的value |
public double getDoubleValue(String key) | 通过String key取获取double 的value |
public BigDecimal getBigDecimal(String key) | 通过String key取获取BigDecimal 的value |
public BigInteger getBigInteger(String key) | 通过String key取获取BigInteger 的value |
public String getString(String key) | 通过String key取获取String 的value |
public Date getDate(String key) | 通过String key取获取Date 的value |
public java.sql.Date getSqlDate(String key) | 通过String key取获取java.sql.Date的value |
public java.sql.Timestamp getTimestamp(String key) | 通过String key取获取 java.sql.Timestamp的value |
public Object put(String key, Object value) | 新增一个key-value |
public void putAll(Map<? extends String, ? extends Object> m) | 像流一样新增可新增key-value,并返回这个JSONObject,可以继续调用JSONObject其他方法 |
public JSONObject fluentPutAll(Map<? extends String, ? extends Object> m) | 将map的所有key-value添加到JSONObject中 |
public JSONObject fluentPutAll(Map<? extends String, ? extends Object> m) | 像流一样新增一个map,并返回这个JSONObject |
public JSONObject fluentClear() | 清空所有key-value |
public Object remove(Object key) | 删除指定的key的对象 |
public JSONObject fluentRemove(Object key) | 删除所有key-value,并返回这个JSONObject |
public Set keySet() | 获取map的Set视图 |
public Set<Map.Entry<String, Object>> entrySet() | 返回一个Set<Map.Entry<String, Object>> 的视图,可用于迭代返回所有元素 |
public Object clone() | 拷贝JSONObject对象 |
public boolean equals(Object obj) | 判断两个JSONObject的每个值是否相等 |
public int hashCode() | 获取JSONObject的hash值 |
public T toJavaObject(Class clazz) | 转化为指定的java class对象 |
public T toJavaObject(Class clazz, ParserConfig config, int features) | 转化为指定的java class对象 |
注:LinkedHashMap继承自HashMap,底层实现与HashMap息息相关。LinkedHashMap很多方法都继承了HashMap,重写的部分比较少。还有JSONObject还支持实现Map接口的类型作为容器,所以部分方法会直接调用其他Map类型的方法,故此以常用的HashMap或者以调用Map接口的XXX方法口吻为主,特别的会提示。
size()底层调用都是返回HashMap的size值,尽管是LinkedHashMap,因为LinkedHashMap继承自 HashMap,并不维护size值。
代码语言:javascript复制 public int size() {
return map.size();
}
isEmpty():判断是否为没有键值对的JSONObject【无需判断null,因为在构造的是否剔除了这种可能】,底层就是判断size== 0? true:false;
代码语言:javascript复制 public boolean isEmpty() {
return map.isEmpty();
containsKey(Object key) 判断JSONObject是否包含此key值
代码语言:javascript复制 public boolean containsKey(Object key) {
return map.containsKey(key);
}
//让我看看HashMap的底层实现:根据key的hash值和key取找,若找到返回该节点,如果没有,则为空
public boolean containsKey(Object key) {
return getNode(hash(key), key) != null;
}
final Node<K,V> getNode(int hash, Object key) {
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) {
if (first.hash == hash && // always check first node
((k = first.key) == key || (key != null && key.equals(k))))
return first;
if ((e = first.next) != null) {
if (first instanceof TreeNode)
return ((TreeNode<K,V>)first).getTreeNode(hash, key);
do {
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
} while ((e = e.next) != null);
}
}
return null;
}
containsValue(Object value): 判断JSONObject是否包含此value值
代码语言:javascript复制public boolean containsValue(Object value) {
return map.containsValue(value);
}
//HashMap的实现:逐个遍历HashMap的桶中的每个个元素,如果值相等返回true,遍历了所有元素都没有则返回false.
public boolean containsValue(Object value) {
Node<K,V>[] tab; V v;
if ((tab = table) != null && size > 0) {
for (int i = 0; i < tab.length; i) {
for (Node<K,V> e = tab[i]; e != null; e = e.next) {
if ((v = e.value) == value ||
(value != null && value.equals(v)))
return true;
}
}
}
return false;
}
get(Object key):通过key获取对应的key-value对象。底层是先调用Map的get方法获取对象,如果获取的对象为空并且key为数值型则转成字符串型再次调用Map的get方法
代码语言:javascript复制 public Object get(Object key) {
Object val = map.get(key);
if (val == null && key instanceof Number) {
val = map.get(key.toString());
}
return val;
}
看看HashMap的实现:如果e不为null,但他的映射值为null的话,e.value=null。所以返回值 null不一定表示该映射不包含键的映射,故需要继续判断 if (val == null && key instanceof Number)
public V get(Object key) {
Node<K,V> e;
return (e = getNode(hash(key), key)) == null ? null : e.value;
}
getJSONObject(String key):根据key获取JSONObject 对象。底层调用map的get方法获取指定对象,再判断此对象的类型,返回对应类型的对象
代码语言:javascript复制 public JSONObject getJSONObject(String key) {
Object value = map.get(key);
//如果为JSONObject对象,则将结果强转为JSONObject
if (value instanceof JSONObject) {
return (JSONObject) value;
}
//如果为Map对象,则生成指定Map容器的JSONObject
if (value instanceof Map) {
return new JSONObject((Map) value);
}
//如果为Map对象,则生成指定Map容器的JSONObject
if (value instanceof String) {
return JSON.parseObject((String) value);
}
//返回JSONObject
return (JSONObject) toJSON(value);
}
//toJSON是JSON类的方法
//通过判断参数的各种类型,将指定的对象序列化为其参数等价表示的JavaObject
public static Object toJSON(Object javaObject) {
return toJSON(javaObject, SerializeConfig.globalInstance);
}
@SuppressWarnings("unchecked")
public static Object toJSON(Object javaObject, SerializeConfig config) {
if (javaObject == null) {
return null;
}
if (javaObject instanceof JSON) {
return javaObject;
}
if (javaObject instanceof Map) {
Map<Object, Object> map = (Map<Object, Object>) javaObject;
int size = map.size();
Map innerMap;
if (map instanceof LinkedHashMap) {
innerMap = new LinkedHashMap(size);
} else if (map instanceof TreeMap) {
innerMap = new TreeMap();
} else {
innerMap = new HashMap(size);
}
JSONObject json = new JSONObject(innerMap);
for (Map.Entry<Object, Object> entry : map.entrySet()) {
Object key = entry.getKey();
String jsonKey = TypeUtils.castToString(key);
Object jsonValue = toJSON(entry.getValue(), config);
json.put(jsonKey, jsonValue);
}
return json;
}
getJSONArray(String key):根据key获取JSONArray。json数组,使用中括号[ ],里面是一个个json对象。
代码语言:javascript复制 public JSONArray getJSONArray(String key) {
Object value = map.get(key);
if (value instanceof JSONArray) {
return (JSONArray) value;
}
if (value instanceof List) {
return new JSONArray((List) value);
}
if (value instanceof String) {
return (JSONArray) JSON.parse((String) value);
}
return (JSONArray) toJSON(value);
}
以下是三个getObject的重载方法,根据不同的参数获取指定的类型的对象,比如public T getObject(String key, Student.class),我们将获得key映射的Student类型的对象。
代码语言:javascript复制 public <T> T getObject(String key, Class<T> clazz) {
Object obj = map.get(key);
//通过TypeUtils工具类转化成对应的clazz类型
return TypeUtils.castToJavaBean(obj, clazz);
}
/*
public static <T> T castToJavaBean(Object obj, Class<T> clazz){
//底层是判断clazz的类型,然后做出对应措施转成对应class对象
return cast(obj, clazz, ParserConfig.getGlobalInstance());
}
*/
//下面两个方法同理
public <T> T getObject(String key, Type type) {
Object obj = map.get(key);
return TypeUtils.cast(obj, type, ParserConfig.getGlobalInstance());
}
public <T> T getObject(String key, TypeReference typeReference) {
Object obj = map.get(key);
if (typeReference == null) {
return (T) obj;
}
return TypeUtils.cast(obj, typeReference.getType(), ParserConfig.getGlobalInstance());
}
下面方法是通过String key取获取不同类型的值(一般都是我们已知该key映射的值的类型下使用),避免我们使用强转失败的后果。涵盖的类型有:Boolean/boolean,byte[]/Byte,Short/short,Integer/int,Long/long,Float/float,Double/double,BigDecimal,BigInteger,String,Date,java.sql.Date,java.sql.Timestamp,方便我们使用。下面暂只对getBoolean(String key)进行解析,有兴趣的可以看下源码,处理方法思路类似
代码语言:javascript复制 public Boolean getBoolean(String key) {
Object value = get(key);
if (value == null) {
return null;
}
//使用的都是TypeUtils的方法,
return castToBoolean(value);
}
暂对getBoolean的 castToBoolean(value)做解析。
/*com.alibaba.fastjson.util.TypeUtils#castToBoolean:
public static Boolean castToBoolean(Object value){
//value为null则返回null
if(value == null){
return null;
}
//如果是Boolean类型则强转为Boolean
if(value instanceof Boolean){
return (Boolean) value;
}
//如果value是BigDecimal类型,
if(value instanceof BigDecimal){
//intValue先对BigDecimal的值进行判断,当scale在-100~100之间【如:19/100 = 0.19 则 integer=19, scale=2 】
//调用decimal.intValue(),反之调用decimal.intValueExact(),得到int的值, 当int类型的值为1返回true
return intValue((BigDecimal) value) == 1;
}
//如果为数值型【Number是基本类型的父类】,则调用对应包装类的intValue方法返回对应的值
if(value instanceof Number){
return ((Number) value).intValue() == 1;
}
//如果为字符串类型
if(value instanceof String){
//强转
String strVal = (String) value;
//null,NULL,length=0返回null
if(strVal.length() == 0 //
|| "null".equals(strVal) //
|| "NULL".equals(strVal)){
return null;
}
//如果是不区分大小写的"true"或者“1”,返回Boolean的TRUE字段
if("true".equalsIgnoreCase(strVal) //
|| "1".equals(strVal)){
// public static final Boolean TRUE = new Boolean(true);
return Boolean.TRUE;
}
//如果是不区分大小写的"false"或者“0”,返回Boolean的FALSE字段
if("false".equalsIgnoreCase(strVal) //
|| "0".equals(strVal)){
return Boolean.FALSE;
}
//"Y","T","y"返回TRUE
if("Y".equalsIgnoreCase(strVal) //
|| "T".equals(strVal)){
return Boolean.TRUE;
}
//"F","N","f"返回FALSE
if("F".equalsIgnoreCase(strVal) //
|| "N".equals(strVal)){
return Boolean.FALSE;
}
}
//都不满足则抛出异常
throw new JSONException("can not cast to boolean, value : " value);
}
*/
public byte[] getBytes(String key) {
Object value = get(key);
if (value == null) {
return null;
}
return castToBytes(value);
}
public boolean getBooleanValue(String key) {
Object value = get(key);
Boolean booleanVal = castToBoolean(value);
if (booleanVal == null) {
return false;
}
return booleanVal.booleanValue();
}
public Byte getByte(String key) {
Object value = get(key);
return castToByte(value);
}
public byte getByteValue(String key) {
Object value = get(key);
Byte byteVal = castToByte(value);
if (byteVal == null) {
return 0;
}
return byteVal.byteValue();
}
public Short getShort(String key) {
Object value = get(key);
return castToShort(value);
}
public short getShortValue(String key) {
Object value = get(key);
Short shortVal = castToShort(value);
if (shortVal == null) {
return 0;
}
return shortVal.shortValue();
}
public Integer getInteger(String key) {
Object value = get(key);
return castToInt(value);
}
public int getIntValue(String key) {
Object value = get(key);
Integer intVal = castToInt(value);
if (intVal == null) {
return 0;
}
return intVal.intValue();
}
public Long getLong(String key) {
Object value = get(key);
return castToLong(value);
}
public long getLongValue(String key) {
Object value = get(key);
Long longVal = castToLong(value);
if (longVal == null) {
return 0L;
}
return longVal.longValue();
}
public Float getFloat(String key) {
Object value = get(key);
return castToFloat(value);
}
public float getFloatValue(String key) {
Object value = get(key);
Float floatValue = castToFloat(value);
if (floatValue == null) {
return 0F;
}
return floatValue.floatValue();
}
public Double getDouble(String key) {
Object value = get(key);
return castToDouble(value);
}
public double getDoubleValue(String key) {
Object value = get(key);
Double doubleValue = castToDouble(value);
if (doubleValue == null) {
return 0D;
}
return doubleValue.doubleValue();
}
public BigDecimal getBigDecimal(String key) {
Object value = get(key);
return castToBigDecimal(value);
}
public BigInteger getBigInteger(String key) {
Object value = get(key);
return castToBigInteger(value);
}
public String getString(String key) {
Object value = get(key);
if (value == null) {
return null;
}
return value.toString();
}
public Date getDate(String key) {
Object value = get(key);
return castToDate(value);
}
public java.sql.Date getSqlDate(String key) {
Object value = get(key);
return castToSqlDate(value);
}
public java.sql.Timestamp getTimestamp(String key) {
Object value = get(key);
return castToTimestamp(value);
}
下面是多种新增操作。
代码语言:javascript复制 //新增一个key-value
public Object put(String key, Object value) {
return map.put(key, value);
}
//像流一样新增可新增key-value,因为其返回一个JSONObject 对象,可以继续调用JSONObject其他 方法,比如继续新增fluentPut
public JSONObject fluentPut(String key, Object value) {
map.put(key, value);
return this;
}
//将map的所有key-value添加到JSONObject中
public void putAll(Map<? extends String, ? extends Object> m) {
map.putAll(m);
}
//像流一样新增可新增多个map
public JSONObject fluentPutAll(Map<? extends String, ? extends Object> m) {
map.putAll(m);
return this;
}
删除操作
代码语言:javascript复制 //清空所有key-value
public void clear() {
map.clear();
}
//清空所有key-value,并继续JSONObject 其他操作
public JSONObject fluentClear() {
map.clear();
return this;
}
//删除指定的key的对象
public Object remove(Object key) {
return map.remove(key);
}
/*HashMap的实现:通过removeNode找到并删除key-value
public V remove(Object key) {
Node<K,V> e;
return (e = removeNode(hash(key), key, null, false, true)) == null ?
null : e.value;
}
*/
//删除所有key-value,并继续JSONObject 其他操作
public JSONObject fluentRemove(Object key) {
map.remove(key);
return this;
}
keySet():获取map的Set视图【去重】
代码语言:javascript复制 public Set<String> keySet() {
return map.keySet();
}
entrySet()返回一个Set<Map.Entry<String, Object>> 的视图,可用于迭代返回所有元素
代码语言:javascript复制 public Set<Map.Entry<String, Object>> entrySet() {
return map.entrySet();
}
clone():拷贝JSONObject对象,是一个副本。此实现直接通过new一个新的Map,也就是新的JSONObject
代码语言:javascript复制 @Override
public Object clone() {
return new JSONObject(map instanceof LinkedHashMap //
? new LinkedHashMap<String, Object>(map) //
: new HashMap<String, Object>(map)
);
}
equals(Object obj) :判断值是否相等
代码语言:javascript复制 public boolean equals(Object obj) {
return this.map.equals(obj);
}
//hashmap底层实现,如果是同一个对象,则equals为true。如果是Map类型,则迭代每一个元素,判断值是否一样。
public final boolean equals(Object o) {
if (o == this)
return true;
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
if (Objects.equals(key, e.getKey()) &&
Objects.equals(value, e.getValue()))
return true;
}
return false;
}
hashCode() :获取JSONObject的hash值
代码语言:javascript复制 public int hashCode() {
return this.map.hashCode();
}
两个toJavaObject方法:转化为指定的java class对象
代码语言:javascript复制 public <T> T toJavaObject(Class<T> clazz) {
//如果为Map,则直接强转为指定类型T
if (clazz == Map.class) {
return (T) this;
}
//当为Object对象并且不包含@type这个keys,也强转为指定类型T
if (clazz == Object.class && !containsKey(JSON.DEFAULT_TYPE_KEY)) {
return (T) this;
}
//通过TypeUtils工具类转换
return TypeUtils.castToJavaBean(this, clazz, ParserConfig.getGlobalInstance());
}
//根据 不同的ParserConfig转化成指定java对象
public <T> T toJavaObject(Class<T> clazz, ParserConfig config, int features) {
if (clazz == Map.class) {
return (T) this;
}
if (clazz == Object.class && !containsKey(JSON.DEFAULT_TYPE_KEY)) {
return (T) this;
}
return TypeUtils.castToJavaBean(this, clazz, config);
}
注:如有错误的地方或者需要改进的地方,可以评论指出,万分感谢
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/190750.html原文链接:https://javaforall.cn