Fastjson源码阅读:缺陷静态检查(上)
缺陷静态检查 2897
使用工具QAPlug(包含Checkstyle FindBgus PMD)
静态代码检查
缺陷修改意见主要参考:stackoverflow
前言
使用QAPlug工具进行分析,将缺陷主要分为效能、可移植性、可靠性、可维护性、可用性五个方面。本文将分两篇来简单分析代码中缺陷的成因以及解决方案。第一篇将从效能、可移植性、可靠性三方面入手,对每一个错误类型都会给出一个典型的修改案例或意见。
效能 22
Hide Utility Class Constructor 3
工具类应该隐藏public构造器
如果该类仅是实用程序类,那么应该将该类定型并定义一个私有构造函数
这样可以防止默认的无参数构造函数在代码的其他地方使用。此外,还可以将类定型,这样它就不能在子类中进行扩展,这是实用程序类的最佳实践。由于仅声明了一个私有构造函数,因此其他类将无法对其进行扩展,但是将类标记为final仍然是一种最佳实践。
举例
/*
将该类标记为final,以使Sonar(代码检查工具)实际考虑已解决的违规情况。仅添加私有构造函数并不能清除冲突。
*/
public class ServiceLoader {// 省略...private ServiceLoader(){// 不调用}// 省略...
}
Unnecessary Local Before Return 19
返回之前不用的本地变量
举例:
// 修改前
public static final int writeJSONString(OutputStream os, // Charset charset, // Object object, // SerializeConfig config, //SerializeFilter[] filters, //String dateFormat, //int defaultFeatures, //SerializerFeature... features) throws IOException {SerializeWriter writer = new SerializeWriter(null, defaultFeatures, features);try {// 省略...// 修改前int len = writer.writeToEx(os, charset);return len;// 修改为 return writer.writeToex(os, charset)} finally {writer.close();}}
可移植性 1
Replace Hashtable With Map 1
用Map替换Hashtable
public Map<Object, Object> createMap(Type type, int featrues) {if (type == Properties.class) {return new Properties();}if (type == Hashtable.class) {return new Hashtable();// 替换为 return new Map();}if (type == IdentityHashMap.class) {return new IdentityHashMap();}if (type == SortedMap.class || type == TreeMap.class) {return new TreeMap();}// 省略...
}
可靠性 1597
Avoid Catching Throwable 48
避免捕获Throwable
举例:
在catch里抛出Throwable里不被推荐,因为它的范围极其广泛,这个包含了一些运行时异常,如OutOfMemoryError内容溢出,而这些错误应该被单独管理。
因此具体问题具体分析,请指明具体异常
Clone Throws Clone Not Supported Exception 3
clone方法应该抛出CloneNotSupportedException
举例:
// 原
public Object clone() {return new JSONArray(new ArrayList<Object>(list));
}
// 修改后
public Object clone() throws CloneNotSupportedException {return new JSONArray(new ArrayList<Object>(list));
}
Close Resource 11
关闭资源
应该确保资源在使用后关闭 比如InputStream
举例:
public static <T> T parseObject(byte[] bytes, int offset, int len,Charset charset,Type clazz,ParserConfig config,ParseProcess processor,int featureValues,Feature... features) {// ...if (charset == IOUtils.UTF8) {// ...if (chars_len < 0) {InputStreamReader gzipReader = null;try {gzipReader = new InputStreamReader(new GZIPInputStream(new ByteArrayInputStream(bytes, offset, len)), "UTF-8");// ...} catch (Exception ex) {return null;} finally {// ...// 新增gzipReader.close() //此处应该记得抛出IO异常}}// ...}
Compare Objects With Equals 30
应该用equals方法来比较对象
对于对象的引用应该使用equals方法,原因懂的都懂,不过多赘述。
举例:
static class FloorSegment implements Segment {public final static FloorSegment instance = new FloorSegment();public Object eval(JSONPath path, Object rootObject, Object currentObject) {if (currentObject instanceof JSONArray) {JSONArray array = ((JSONArray) ((JSONArray) currentObject).clone());for (int i = 0; i < array.size(); i++) {Object item = array.get(i);Object newItem = floor(item);if (newItem != item) {//此处判断应修改为 !newItem.equals(item)array.set(i , newItem);}}return array;}return floor(currentObject);}
Constructor Calls Overridable Method 16
在构造方法中调用覆写的方法不妥当,存在风险
有风险。构造方法调用不是原子的,因此,如果在另一个线程中调用实例方法,那么从构造方法推迟实例方法的调用也同样安全,因为不能保证在(最终)调用线程时完全构造对象。
现在,假设,如果子类对象被完全构造(重点是假设),那么未来的回调将是安全的。换句话说,它不会绕过部分构造的对象,这与其说是危险的,还不如说是访问它。
这是有风险的,因为在完全构建测试对象之前,会将它暴露给第二个线程。
如果需要通过调用hello来控制测试实例的初始化,请考虑使用工厂方法进行实例化。将其与私有构造方法相结合,可以保证在所有测试对象上安全地调用hello:
Design For Extension 270
如果类不是为扩展而设计的,考虑将类final或使方法’write’ static/final/abstract/empty,或为方法添加允许的
Magic Number 1194
魔数:代码中出现的没有说明的数字
具体问题具体分析,FastJson中的魔数主要表现在1024、0xff以及设计特殊需要 没啥好说的
Security Array is stored directly 24
一般是数组浅拷贝和深拷贝的问题
举例:
public Context(FieldInfo[] getters, //SerializeBeanInfo beanInfo, //String className, //boolean writeDirect, //boolean nonContext){this.getters = getters;// 改为 this.getters = Arrays.copyOf(getters, getters.length)this.className = className;this.beanInfo = beanInfo;this.writeDirect = writeDirect;this.nonContext = nonContext || beanInfo.beanType.isEnum();}
String Literal Equality 1
字符串比较应使用equals
字符串应使用equals()方法进行比较,而非’==’。
if ("$ref" == key && context != null) {// 修改为"$ref".equals(key)// ...
}
最后
该文章仅用于学习记录及交流,若有错误还望理解。
Fastjson源码阅读:缺陷静态检查(上)相关推荐
- scrcpy源码阅读及在Ubuntu上的实现(一)——了解原理
那开篇就问问为什么需要研究这个源码吧: 在移动互联网的时代下,手机的功能是日益增加的,要使工作变得更加的高效,那么键盘鼠标其实是必不可少的.在许多软件的架构中,其实并没有提供对应的桌面版本,也不兼容基 ...
- scrcpy源码阅读及在Ubuntu上的实现(三)——使用ZeroMQ传输yuv数据并使用Python订阅
目录 0x01 什么是ZeroMQ? 0x02 ZeroMQ的消息模型 0x03 回到任务 0x04 封装我们的yuv图像以及发布者 0x05 使用Python订阅ZeroMQ的发布 0x06 需要注 ...
- 【Dubbo源码阅读系列】之远程服务调用(上)
今天打算来讲一讲 Dubbo 服务远程调用.笔者在开始看 Dubbo 远程服务相关源码的时候,看的有点迷糊.后来慢慢明白 Dubbo 远程服务的调用的本质就是动态代理模式的一种实现.本地消费者无须知道 ...
- mybatis源码阅读(二):mybatis初始化上
转载自 mybatis源码阅读(二):mybatis初始化上 1.初始化入口 //Mybatis 通过SqlSessionFactory获取SqlSession, 然后才能通过SqlSession与 ...
- 基于lis3dh的简易倾角仪c源码_开源网关apisix源码阅读和最佳实践
大家应该都接手过这种项目,前人找一个开源软件改一改,发上线. 我这里便曾经遇到过类似的问题. 随着需求的增加,各种维护人员东改改西改改,原来的开源项目被改的面目全非,再也无法和上游合并. 甚至TLS协 ...
- MyBatis 源码阅读 -- 核心操作篇
核心操作包是 MyBatis 进行数据库查询和对象关系映射等工作的包.该包中的类能完成参数解析.数据库查询.结果映射等主要功能.在主要功能的执行过程中还会涉及缓存.懒加载.鉴别器处理.主键自增.插件支 ...
- React 表单源码阅读笔记
1 概念 1.1 什么是表单 实际上广义上的表单并不是特别好界定,维基上讲表单是一系列带有空格的文档,用于输写或选择.更具体的,在网页中表单主要负责数据采集的功能,我们下文中所提到的表单都指后者.如下 ...
- vue-router 源码阅读 - 文件结构与注册机制
文章目录 0. 前备知识 1. 文件结构 2. 入口文件 2.1 rollup 出口与入口 2.2 Vue.use 3. 路由注册 3.1 install 3.2 VueRouter 前端路由是我们前 ...
- Android源码阅读---init进程
Android源码阅读-init进程 文章目录 Android源码阅读---init进程 1. 编译命令和进程入口 1. init 进程编译命令 2. main函数流程 2. 主函数处理流程 1. 创 ...
- μC/OS-II 源码阅读笔记 —— 内核深度剖析
一个程序猿郁结十年的青苹果 Bush 2014-4-24 前言 此文发表在此,由于正吃菜的我才疏学浅,文中难免有错误的地方,欢迎看官和过客指正批评,痛骂也无妨,我虚心接受所有的鄙视. 目录 概述 缩略 ...
最新文章
- QIIME1.9.1-2使用Docker运行QIIME
- [NodeJS]Node异步编程基础
- Stream is the new file
- 关于Ad-hoc测试的基本知识
- 设置第三方的SMTP服务
- java开发plc上位机软件开发_上位机开发之西门子PLC-S7通信实践
- (四)ElasticSearch之数据
- 机器学习笔记(十三):降维
- CentOS 7.0安装配置Vsftp服务器
- developerDiskImage文件提取
- Android开发教程 - 使用Data Binding Android Studio不能正常生成相关类/方法的解决办法...
- 小新700linux网卡驱动,联想小新air无线网卡驱动-联想小新air笔记本无线网卡驱动下载v2.1 官方最新版-西西软件下载...
- 网吧游戏服务器制作教程,网吧服务器系统环境部署
- HTML基础(新手入门教程)
- c++语言杨辉三角,杨辉三角 (C++代码)
- 实训项目名称: 双绞线的制作
- STM32名字含义以及其与ARM公司的关系
- sql同比环比 简单示例
- 2021华为鸿蒙发布会直播,2021 华为智能协作春季发布会直播(视频)
- 验证码爬取并识别-云大urp教务系统大作战(1)
热门文章
- 光纤猫可做无线打印服务器吗,光猫自带的天线,这些天线都有什么用呢?是无线功能吗?...
- PHP 递归算法操作文件编程
- 独家汉化SDL Passolo 2018(软件汉化工具) v18.0.130简体中文版
- iframe标签用法详解
- ThinkPad E450 10.11 驱动HD4400的注意即解决方法
- 中国机床行业投资现状与十四五发展战略决策报告2022版
- Sopcast for linux更新至3.01!
- 高等数学在计算机的应用论文,计算机技术在高等数学教学中的应用
- 24小时改变你的人生 (1至12小时)很好的书,推荐大家有时间在网上看看。
- 最全盘点:27类激光技术前沿应用