java开发150个建议( 十 )


下面展示一个优秀的方案,其中实现了接口的类可以实现两个私有方法:和,以影响和控制序列化和反序列化的过程 。我们把类稍作修改,看看如何控制序列化和反序列化,代码如下:
1 public class Person implements Serializable {2 3private static final long serialVersionUID = 9146176880143026279L;4 5private String name;6 7private transient Salary salary;8 9public Person(String _name, Salary _salary) {10this.name = _name;11this.salary = _salary;12}13//序列化委托方法14private void writeObject(ObjectOutputStream oos) throws IOException {15oos.defaultWriteObject();16oos.writeInt(salary.getBasePay());17}18//反序列化委托方法19private void readObject(ObjectInputStream input)throws ClassNotFoundException, IOException {20input.defaultReadObject();21salary = new Salary(input.readInt(), 0);22}23 }
其它代码不做任何改动,运行之后结果为:姓名: 张三 基本工资: 1000 绩效工资: 0
在类中增加了和两个方法,并且访问权限都是私有级别,为什么会改变程序的运行结果呢?其实这里用了序列化的独有机制:序列化回调 。Java调用类把一个对象转换成数据流时,会通过反射()检查被序列化的类是否有方法,并且检查其是否符合私有,无返回值的特性,若有,则会委托该方法进行对象序列化,若没有,则由按照默认规则继续序列化 。同样,在从流数据恢复成实例对象时,也会检查是否有一个私有的方法,如果有,则会通过该方法读取属性值,此处有几个关键点需要说明:
oos.():告知JVM按照默认的规则写入对象,惯例的写法是写在第一行 。input.():告知JVM按照默认规则读入对象,惯例的写法是写在第一行 。oos.和input.
分别是写入和读出相应的值,类似一个队列,先进先出,如果此处有复杂的数据逻辑,建议按封装对象处理 。大家可能注意到上面的方式也是失去了分布式部署的能了,确实是,但是HR系统的难点和重点是薪水的计算,特别是绩效工资,它所依赖的参数很复杂(仅从数量上说就有上百甚至上千种),计算公式也不简单(一般是引入脚本语言,个性化公式定制)而相对来说类基本上都是静态属性,计算的可能性不大,所以即使为性能考虑,类为分布式部署的意义也不大 。
回到顶部
建议15:break万万不可忘
我们经常会写一些转换类,比如货币转换,日期转换,编码转换等,在金融领域里用到的最多的要数中文数字转换了,比如把"1"转换为"壹",不过开源工具是不会提供此工具类的,因为它太贴近中国文化了,需要自己编写:
1 public class Client15 {2public static void main(String[] args) {3System.out.println(toChineseNuberCase(0));4}5 6public static String toChineseNuberCase(int n) {7String chineseNumber = "";8switch (n) {9case 0:10chineseNumber = "零";11case 1:12chineseNumber = "壹";13case 2:14chineseNumber = "贰";15case 3:16chineseNumber = "叁";17case 4:18chineseNumber = "肆";19case 5:20chineseNumber = "伍";21case 6:22chineseNumber = "陆";23case 7:24chineseNumber = "柒";25case 8:26chineseNumber = "捌";27case 9:28chineseNumber = "玖";29}30return chineseNumber;31}32 }
这是一个简单的代码,但运行结果却是"玖",这个很简单,可能大家在刚接触语法时都学过,但虽简单,如果程序员漏写了,简单的问题会造成很大的后果,甚至经济上的损失 。所以在用语句上记得加上break,养成良好的习惯 。对于此类问题,除了平常小心之外,可以使用单元测试来避免,但大家都晓得,项目紧的时候,可能但单元测试都覆盖不了 。所以对于此类问题,一个最简单的办法就是:修改IDE的警告级别,例如在中,可以依次点击-->Java-->-->/-->,然后修改'' case fall-为级别,如果你胆敢不在case语句中加入break,那直接就报个红叉给你看,这样可以避免该问题的发生了 。但还是啰嗦一句,养成良好习惯更重要!