提升Java代码质量(一)
博主双12入手了一本"Effective Java第二版",本系列文章将初步梳理书中内容,我也查了些资料,我会针对知识点做一点展开,方便以后复习回顾;
Item1.考虑用静态工厂代替构造器:
静态工厂的优势:
|
更易于阅读(有名称) |
| 可以做成单例(Singleton)的 |
| 可以实现多态(返回多个子类型的对象) |
| 在创建参数化类型的实例时,他们使代码变得更加简洁 |
静态工厂存在的不足:
1.类如果不含共有的或者受保护的构造器,就不能被子类化;
2.他们与其它的静态方法其实没区别,因此对于客户来说如何使用变成了难题.
Item2:对于多个构造器参数时,利用构建器(Builder Mode):
利用构造器重载确实可以解决少量构造器参数对象的初始化,但大量比如十几个甚至几十个的时候,客户端的代码很难编写,更别说阅读了,建议用建造者模式来解决;
建造者模式的核心就是:将需要的域(包括必须的参数和不必须的参数)放在一个Builder类中,必须的参数放在Builder的构造器中初始化(只要用到Builder对象就会调用其构造器),可选参数利用对应的set方法供客户端调用实现初始化:
//Builder Parttern
public class User {
private final String userName;
private final String pwd;
private final String mobile;
private final String e_mail; public static class Builder {
//Required parameters
private final String userName;
private final String pwd; //Optional parameters - initialized to default values
private final String mobile = "13900000000";
private final String e_mail = "1@1.com"; public Builder(String userName, String pwd){
this.userName = userName;
this.pwd = pwd;
} public Builder mobile(String mobile){
this.mobile = mobile;
return this;
} public Builder e_mail(String e_mail){
this.e_mail = e_mail;
return this;
} public User build(){
return new User(this);
}
} private User(Builder builder){
userName = builder.userName;
pwd = builder.pwd;
mobile = builder.mobile;
e_mail = builder.e_mail;
}
} //Client Code
User user = new User.Builder("Joey","123").mobile("13512511111").
e_mail("joey@gmail.com");
但建造者模式实现也不是完美的,为了创建对象,必须先创建其构建器,在十分注重性能的场景下,它有可能比重载构造器更加冗长,如果要用建造者模式,最好一开始就用(不要和构造器或静态工厂混用).
Item3:用私有构造器或者枚举类型强化Singleton属性:
我们平常构造Singleton的时候,一般先私有化构造器,再利用静态工厂控制对象,但享有特权的客户端可以借助AccessibleObject.setAccessible方法,通过反射机制调用私有构造器,如果要抵御这种攻击,可以改造构造器,让构造器创建第二个实例的时候抛出异常;
当然有更好的方法,只需编写一个包含单个元素的枚举类型:
public enum Singleton {
INSTANCE;
public void leaveTheBuilding(){...}
}
此方法既可以完美地防止了多次实例化,并无偿提供了序列化机制,即便面对复杂序列化或反射攻击的时候.....
Item4:避免创建不必要的对象:
此条目涵盖的内容比较多,中心点就是能重用(immutable)的对象就不要去创建一个相同功能的对象.下面有些例子:
1.尽量少用new String(),推荐把字符串放入常量池:String str = "abc";
2.方法中实例化Calendar类的对象,若多次调用,会产生多个相同功能的对象,解决办法:写一个静态代码块,可重用的对象或者变量都可以放进去;
3.适配器(adapter)模式中,有些特定的适配器不需要多个适配器实例,例如:Map接口的keySet方法返回Map中key的Set,感觉上,每次调用keySet都创建了一个新的实例,实际上用的是同一个实例,因为此实例的作用是一样的,虽然多个实例是没有害处的,同样,没有必要这么做;
4.再Java1.5的发行版本中,拥有自动装箱(autoboxing)的新特性,观察以下代码:
public static coid main(String []args){
Long sum = 0L;
for(long i = 0; i < Integer.MAX_VALUE; i++){
sum += i; //无意识的自动装箱
}
System.out.println(sum);
}
自动装箱的过程中会自动创建包装类的实例,如果执行完上面的代码,JVM会多构造了大约231个实例,如果将sum定义为基本数据类型long,性能将会提高几倍..
当然并不意味着我们必须尽可能地避免创建对象,通过创建代价不大的小对象来提升程序的清晰性和间接性是非常好的.
总结一句就是:当你应该重用对象的时候,请不要创建新的对象;当你应该创建新对象的时候,请不要重用对象..
提升Java代码质量(一)的更多相关文章
- 提升Java代码质量(三)
Item7:覆盖equals时需要遵守通用约定 在我们日常开发过程中,重写equals是比较常用的,但存在许多不合适的覆盖方式导致错误,最好的避免方法就是不去重写equals.但有时我们的业务又需要建 ...
- 提升Java代码质量(二)
Item5:消除过期对象的引用 JVM为我们实现了GC(垃圾回收)的功能,让我们从手工管理内存中解放了出来,这固然很好,但并不意味着我们就再也不需要去考虑内存管理的事情了;我们用简单的栈实现的例子来解 ...
- 拔高你的Java代码质量吧:推荐使用枚举定义常量(转)
提高你的Java代码质量吧:推荐使用枚举定义常量 一.分析 常量的声明是每一个项目中不可或缺的,在Java1.5之前,我们只有两种方式的声明:类常量和接口常量.不过,在1.5版之后有了改进,即新增了一 ...
- 提高Java代码质量的Eclipse插件之Checkstyle的使用详解
提高Java代码质量的Eclipse插件之Checkstyle的使用详解 CheckStyle是SourceForge下的一个项目,提供了一个帮助JAVA开发人员遵守某些编码规范的工具.它能够自动化代 ...
- java 性能优化:35 个小细节,让你提升 java 代码的运行效率
前言 代码 优化 ,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没 ...
- JAVA性能优化:35个小细节让你提升java代码的运行效率
代码优化,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没用,但是, ...
- 提高Java代码质量的Eclipse插件之Checkstyle的使用具体解释
CheckStyle是SourceForge下的一个项目,提供了一个帮助JAVA开发者遵守某些编码规范的工具.它可以自己主动化代码规范检查过程.从而使得开发者从这项重要可是枯燥的任务中解脱出来. Ch ...
- Java基础学习总结(72)——提升 java 代码的运行效率
前言 代码 优化 ,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没 ...
- Java代码质量监控工具Sonar安装
1. 代码质量七宗罪 Sonar是一个代码质量管理系统.它的帮助文档开篇明义,提出了代码质量的七宗罪.总结的比較到位.最好还是一看: 1. Bug和隐藏Bug(Bugs and Pot ...
随机推荐
- codevs2821 天使之城
传送门 2821 天使之城 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 天使城有一个火车站,每辆火车都从A方向驶入车站 ...
- 【Lintcode】106.Convert Sorted List to Balanced BST
题目: Given a singly linked list where elements are sorted in ascending order, convert it to a height ...
- Node初学者入门,一本全面的NodeJS教程
作者: Manuel Kiessling 翻译: goddyzhao & GrayZhang & MondayChen 关于 本书致力于教会你如何用Node.js来开发应用,过程中会 ...
- poj3468区间加减查找——树状数组区间修改查询
题目:http://poj.org/problem?id=3468 增加一个更改量数组,施以差值用法则区间修改变为单位置修改: 利用公式可通过树状数组维护两个数组:f与g而直接求出区间和. 代码如下: ...
- mina2中的线程池
一.Mina中的线程池模型 前面介绍了Mina总体的层次结构,那么在Mina里面是怎么使用Java NIO和进行线程调度的呢?这是提高IO处理性能的关键所在.Mina的线程调度原理主要如下图所示: A ...
- 四 akka学习 四种多线程的解决方案
http://blog.csdn.net/chenleixing/article/details/44044243 四种多线程的解决方案
- Linux 包管理基础:apt、yum、dnf 和 dpkg
https://linux.cn/article-8782-1.html 1. apt-get 安装( 在线) 会帮我把所有的依赖包都一起安装 apt-get install xxx 安装xxx .如 ...
- Windows窗体间的数据交互
轻松掌握Windows窗体间的数据交互 作者:郑佐 2004-04-05 Windows 窗体是用于 Microsoft Win ...
- c#实现最简快速排序,你绝对可以看懂
原创文章,转载请注明出处 算法对于程序员的重要性不言而喻,今天我和大家分享算法中的一个基础算法,快速排序.作为一名程序员,相信大家都不陌生,但是要大家徒手一次性写出来,我估计还是有难度的.那么废话不多 ...
- Linux之vim基本命令操作
安装vim(yum -y install vim) 三种工作模式(命令模式.输入模式.编辑模式) 打开文件( vi ) 查找文本( / ) 替换文本 删除文本( dd 删除光标所在行 ) 复制文本 去 ...