通用的方法和准则
尽量显示声明UID
在编写一个可序列化的类(implements Serializable)时,尽量要显式声明serialVersionUID
。当我们把一个对象序列化后储存或通过网络传输后,若想要将其反序列化,Java会检测其UID
是否相同,如果不同,就会抛出InvalidClassException
的异常。如果我们不显示指定serialVersionUID
,编译器在编译时会根据包名、类名等属性生成一个独一无二的UID
,那么当我们的类改变不大,却又想让JVM反序列化时,就遇到麻烦了。显示声明UID
可以“骗过”JVM,告诉它我这还是一个类,可以方便地做到向下兼容,当出现巨大改变的时候,我们仍可以手动修改UID
。
附: 显式声明的格式
1 | private static final long serialVersionUID = XXXXXXXXXL; |
在序列化类中,不使用构造函数为final变量赋值
反序列化时构造函数不会执行!!
在发布应用时不要只替换一个类
对于final
修饰的基本类型和String
类型,编译器会认为它是稳定态,所以在编译时直接把值编译到字节码中了。但这个问题在当前主流的IDE中都不存在,它们都默认编译所有的引用类。
基本类型
用偶判断,不用奇判断
-1 % 2 == 1
返回false
模拟取余计算:
1 | public static int remainder(int dividend, int divisor) { |
由此也可知 -1 mod 2
的值为 -1
优先选择基本类型
自动装箱(拆箱)虽然很方便,但引起的问题往往很隐蔽,比如int
无法被转换成Long
,出现NPE等等。
若非必要,不要设置随机数种子
系统会默认帮你做的。设置了反而会让随机数不那么随机。
类、对象及方法
使用构造代码块精练程序
构造代码指的是没有任何前缀或后缀,并使用{}
括起来的代码片段。编译器会把构造代码块插入到每个构造函数的最前端。
让工具类不可实例化
1 | public final class Math { |
字符串
推荐使用String直接量赋值
使用String s = "xxxx"
的方法赋值而不是String s("xxxx")
可以最大限度地利用对象池,达到更好的性能。
正确使用String、StringBuffer、StringBuilder
String
:字符串不经常变化
StringBuffer
:进行频繁的字符串运算,且运行在多线程环境中
StringBuilder
:进行频繁的字符串运算,且运行在单线程环境中