十一、 养成良好习惯,显示声明UID
JVM通过SerialVersionUID(也叫作流标识符)来判断一个类的版本。
SerialVersionUID的作用:
JVM在反序列化时,会比较数据流中的SerialVersionUID与类的SerialVersionUID是否相同。
如果相同,则认为类没有发生变化,可以把数据流load为实例对象;
如果不相同,JVM抛出异常InvalidClassException。
显示声明SerialVersionUID可以避免对象不一致,但尽量不要以这种方式向JVM“撒谎”。
十二、避免用序列化类在构造函数中为不变量赋值
反序列化时构造函数不会执行。
反序列化的执行过程如下:
JVM从数据流中获取一个Object对象,然后根据数据流中的类文件描述信息(在序列化时,保存到磁盘的对象文件中
包含了类描述信息,注意是类描述信息,不是类)查看,发现是final变量,需要重新计算,于是引用Person类中的
name值,而此时JVM又发现name居然没有赋值,不能引用,于是它很“聪明”的不再初始化,保持原值状态。
在序列化类中,不使用构造函数为final变量赋值。
十三、避免为final变量复杂赋值
final变量赋值方式:
1. 通过构造函数赋值
2. 通过方法赋值,即直接在声明中通过方法返回值赋值
反序列化时final变量在以下情况下不会被重新赋值:
* 通过构造函数为final变量赋值
* 通过方法返回值为final变量赋值
* final修饰的属性不是基本类型
十四、 使用序列化类的私有方法巧妙解决部分属性持久化问题
十五、break万万不可忘
记住在case语句后面随手写上break,养成良好的习惯。
十六、易变业务用脚本语言编写
十七、慎用动态编译
在动态编译时需要注意以下几点:
- 在框架中谨慎使用
- 不要在要求高性能的项目中使用
- 动态编译要考虑安全问题
- 记录动态编译过程
十八、避免InstanceOf非预期结果
十九、断言绝对不是鸡肋
在java中断言使用的是Assert关键字,其基本的用法如下:
assert <布尔表达式>
assert <布尔表达式> : <错误信息>
在以下两种情况下不可以使用:
- 在对外公开的方法中
- 在执行逻辑代码的情况下
那么在什么情况下可以使用assert呢?一句话:按照正常执行逻辑不可能到达代码区域可以设置assert。具体分为你三种情况:
- 在私有方法中放置assert作为输入参数的校验
- 流程控制中不可能到达的区域
- 建立程序探针
二十、不要只替换一个类
发布应用系统时禁止使用类文件替换方式,整体war包发布才是万全之策。