反例:
StringBuffer sb = new StringBuffer(); //超过 120 个字符的情况下,不要在括号前换行 sb.append("zi").append("xin")...append ("huang"); //参数很多的方法调用可能超过 120 个字符,不要在逗号前换行 method(args1, args2, args3, ... , argsX);关于换行,Google并没有给出明确的要求,而阿里巴巴则给出了强制性的要求。Google特别提示可以通过一些重构手法来减少单行字符长度从而避免换行,这一点我颇为认同。关于参数,很多方法调用超过120个字符需要换行,这暴露除了过长参数列的代码坏味道,解决方式之一就是使用重构手法的Replace Parameter With Method的方式把一次方法调用化为多次方法调用,或者使用Introduce Parameter Object手法创造出参数对象并进行传递。
17. 【推荐】循环体内,字符串的联接方式,使用 StringBuilder 的 append 方法进行扩展。 反例:
String str = "start"; for (int i = 0; i < 100; i++) { str = str + "hello"; }说明:反编译出的字节码文件显示每次循环都会 new 出一个 StringBuilder 对象,然后进行append 操作,最后通过 toString 方法返回 String 对象,造成内存资源浪费。
这是《Effective Java》以及其他文章中经常提及的优化方式,而且面试初级Java工程师时几乎是一个必考点。其实不仅是在循环体内,所有需要进行多次字符串拼接的地方都应该使用StringBuilder对象。
20. 【推荐】类成员与方法访问控制从严:
1) 如果不允许外部直接通过 new 来创建对象,那么构造方法必须是 private。
2) 工具类不允许有 public 或 default 构造方法。
3) 类非 static 成员变量并且与子类共享,必须是 protected。
4) 类非 static 成员变量并且仅在本类使用,必须是 private。
5) 类 static 成员变量如果仅在本类使用,必须是 private。
6) 若是 static 成员变量,必须考虑是否为 final。
7) 类成员方法只供类内部调用,必须是 private。
8) 类成员方法只对继承类公开,那么限制为 protected。
说明:要严控类、方法、参数、变量的访问范围。过宽泛的访问范围不利于模块解耦。思 考:如果是一个 private 的方法,想删除就删除,可是一个 public 的 Service 方法,或者一个 public 的成员变量,删除一下,不得手心冒点汗吗?变量像自己的小孩,尽量在自己的视线内,变量作用域太大,会无限制的到处跑,那么你会担心的。
这其实就是经典的原则‘Principle of least privilege’ 的体现。我们必须遵循这一原则,但不知为何阿里巴巴将其级别列为“推荐”。
7. 【参考】方法中需要进行参数校验的场景:
1) 调用频次低的方法。
2) 执行时间开销很大的方法,参数校验时间几乎可以忽略不计,但如果因为参数错误导致 中间执行回退,或者错误,那得不偿失。
3) 需要极高稳定性和可用性的方法。
4) 对外提供的开放接口,不管是 RPC/API/HTTP 接口。
5) 敏感权限入口。
8. 【参考】方法中不需要参数校验的场景:
1) 极有可能被循环调用的方法,不建议对参数进行校验。但在方法说明里必须注明外部参 数检查。
2) 底层的方法调用频度都比较高,一般不校验。毕竟是像纯净水过滤的最后一道,参数错 误不太可能到底层才会暴露问题。一般 DAO 层与 Service 层都在同一个应用中,部署在同一台服务器中,所以 DAO 的参数校验,可以省略。
3) 被声明成 private 只会被自己代码所调用的方法,如果能够确定调用方法的代码传入参数已经做过检查或者肯定不会有问题,此时可以不校验参数。