2021SC@SDUSC
JSONObject
我们上次分析也聊过,在我们前面分析的APIJSON项目中用到了一个十分频繁的对象就是我们的JSONObject,而JSONObject时来自于FASTJSON里面的一个类,其中定义了一些方法和操作,我们也来看一下这个类,方便我们更好的理解APIJSON的原理和依赖关系:
public class JSONObject extends JSON implements Map<String, Object>, Cloneable, Serializable, InvocationHandler
我们可以看到,这个JSONObject是继承于JSON而且实现了Cloneable、Serializable和InvocationHandler,我们这次就来树立一下这几个父类的作用,以及为什么要实现这几个类,实现后又该怎么去做,最后怎么关联到我们的APIJSON项目。
Cloneable
注意这个类有三个需要实现,分别是Cloneable,Serializable,InvocationHandler。首先是第一个Cloneable,Cloneable是标记型的接口,我们知道类对象的克隆一般需要我们单独的去写一个方法,否则会报错,而实现Cloneable便可以帮助我们解决这个问题,它们内部都没有方法和属性,实现 Cloneable来表示该对象能被克隆,能使用Object.clone()方法。如果没有实现 Cloneable的类对象调用clone()就会抛出CloneNotSupportedException。
Serializable
然后是Serializable,持久化”意味着对象的“生存时间”并不取决于程序是否正在执行——它存在或“生存”于程序的每一次调用之间。通过序列化一个对象,将其写入磁盘,以后在程序再次调用时重新恢复那个对象,就能圆满实现一种“持久”效果。而且最明显的一个特点就是使用一个Java Bean 时,它的状态信息通常在设计期间配置好。程序启动以后,这种状态信息必须保存下来,以便程序启动以后恢复;具体工作由对象序列化完成。同时我们并不需要去实现方法,只需要实现Serializable就可以了。
InvocationHandler
最后是InvocationHandler,这个就是动态代理,也就是说对象的执行方法,交给代理来负责。比如user.get() 方法,是User对象亲自去执行。而使用代理则是由proxy去执行get方法。举例来说:投资商找明星拍广告,投资商是通过经纪人联系的,经纪人可以帮明星接这个广告,也可以拒绝。做不做,怎么做都叫给经纪人和投资商谈。
我们需要实现的是:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
而这个invoke的作用于实现就是去根据当前的情况去设置一个动态的代理而不是直接去打交道,这也是我们程序设计的一个方法和思想。
然后回到我们当前类,我么你主要实现的方法就是Map接口的一些方法包括size(),isEmpty(),containKey()等方法,主要就是为了实现我们的一下JSON的方法比如:
public JSONObject getJSONObject(String key) {
Object value = map.get(key);
if (value instanceof JSONObject) {
return (JSONObject) value;
}
if (value instanceof Map) {
return new JSONObject((Map) value);
}
if (value instanceof String) {
return JSON.parseObject((String) value);
}
return (JSONObject) toJSON(value);
}
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);
}
无论如何最后都是调用了系统的toJSON方法,把Object对象转换为了JSON对象。
我们看一下一个类型判断的函数:
public <T> T getObject(String key, Class<T> clazz) {
Object obj = map.get(key);
return TypeUtils.castToJavaBean(obj, clazz);
}
这里是用了类型工具的castToJavaBean方法,这个方法就是讲相应的clazz类型进行转化:
public static <T> T cast(Object obj, Class<T> clazz, ParserConfig config){
if(obj == null){
if(clazz == int.class){
return (T) Integer.valueOf(0);
} else if(clazz == long.class){
return (T) Long.valueOf(0);
} else if(clazz == short.class){
return (T) Short.valueOf((short) 0);
} else if(clazz == byte.class){
return (T) Byte.valueOf((byte) 0);
} else if(clazz == float.class){
return (T) Float.valueOf(0);
} else if(clazz == double.class){
return (T) Double.valueOf(0);
} else if(clazz == boolean.class){
return (T) Boolean.FALSE;
}
return null;
}
数据类型全部进行了一个默认赋值操作。
接着实现的就都是一些数据类型的操作:
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();
}
同理还有很多比如Boolean,int,string等数据类型都有。这个就是很基本的、很底层的东西了,这是为了实现项目而再次重新写的数据类型转换。
与小组成员讨论
这次为了弄懂三个接口的作用,我先是与组员进行了讨论,后来觉得大家都不太理解,我便在网上查阅了很多的资料,但大家的说法千奇百怪,我只能一个个的看,然后我自己根据自己的理解,将它们进行了汇总,去问了问技术群里面的大佬,最后他们也觉得我理解没问题,然后便与组员进行了相关知识的分享,在这个过程中大家的受益匪浅,对于JSON对象与JSONObject对象的相关作用以及如何实现、如何进行,对这种底层的JSON知识也是更加深入理解了。