您的位置:首页 > 编程语言 > Java开发

java进阶——从基础重构编写更具质量的代码

2016-03-11 17:59 260 查看

引言

无论是由于经验的欠缺,还是工作任务的时间的紧迫,抑或是其他的客观主观原因。我们常常在编写代码的时候容易忽略一些所谓的代码质量,正所谓条条大路通罗马,一个问题解决方案有很多种,一个方法的实现也有很多种,但有很多的细节我们是可以优化下的,暂不论是否能提高多少的性能,至少在笔者看来是可以改造得更美一些的。以下笔者结合个人的项目经验及能力总结了几条建议。

一、代码块和静态代码块

1、代码块的概念及应用

//代码块的形式,如果有static 修饰符 就是静态代码块
[static]{
//代码语句
}


当创建java对象时,系统总是先调用该类中定义的初始化代码块,如果有两个代码块,则按先后顺序执行,初始化代码块虽然也可以看成是java的一种成员但是它没有名字,无法通过类或者对象去调用初始化代码块,仅仅是在创建java对象时隐式执行,而且是在构造方法之前执行。

虽然代码块总是在构造器执行之前执行,但它不能接收任何参数,对于一个类中所有的对象所进行的初始化操作处理完全相同。所以如果两个构造器中有相同的初始化代码且无需接收参数,就可以提取到代码块中去实现。当然当我们创建一个java对象的时候不仅仅会执行该类的普通初始化代码块和构造器,还会上溯到Object的初始化块,再执行Object 的构造器,再一次执行这个类的父类的初始化块,再到父类的构造器,最后才是本类的初始化块和构造器,最终返回本类的对象

2、静态代码块的概念及应用

//静态代码块
static{
//代码语句
}


当使用了static修饰符修饰的代码块之后即静态初始化代码块也叫类初始化块,静态代码块会比普通的代码块先执行,假如有这么一个需求当Employee类加载了之后,需要把Employee的类Filed Wage初始化为10000,此时我们可以使用static关键字来初始化代码块。由于静态代码块是类相关的,用于对整个类的类Filed 初始化处理,自然不能对实例Filed处理。创建一个java对象的时候也会上溯到Object,其他相关机制与普通代码块类似。

二、 == 和Equals

java中有两种测试两个变量是否相等的方法:一种是利用==运算符,另一种是利用Equals

1、==

1.1、基本类型的变量的比较

当使用==来判断时,如果两个变量是基本类型的变量且都是数值类型(不一定数据类型严格相同),则只要两个变量的值相等就返回true,如:int key=65;float key2=65.0f;key==key2 输出true,再比如char ch=’A’;key==ch输出true;

1.2、引用类型变量的变量比较

但是对于引用类型变量,他们必须指向同一个对象的时候==才会返回true,且要注意的是==不能用于比较两个类型上没有父子关系的对象

String str=new String("helloworld");
String str2=new String("helloworld");
str==str2 //返回false;而这条语句则会报错:"Dog"==new Dog();


2、Equals

2.1、Equals 判断结果并非是基于两个对象的值是否相等

使用Equals,并非许多教材中所说的那样是判断,两个对象的值是否相等,或许是因为String类型造成的误解吧,实际上String是重写了Object的equals方法,具体实现的思路就是只要两个字符串包含的字符串序列相同则认为两个String相同,即返回true,换言之,equals比较两个对象是否相等的标准是基于是否重写了equals方法而言的即equals方法里的判断逻辑

2.2、重写equals方法的必须遵守的原则:

自反性:对任意x,x.equals(x)一定恒返回true

对称性:对于任意x,y, x.equals(y)返回true,则y.equals(x)也一定返回true

传递性:对于x,y,z,如果x.equals(y)返回true,y.equals(z)也返回true,那么x.equals(z)也一定返回true

一致性:无论调用多少次x.equals(y)返回的结果必须一致,对于任何不是null的x,x.equals(null)一定返回false

三、使用obj .getClass()==Student.class代替obj instanceof Student

在判断obj是否为某一类的实例时候,应当少用obj instanceof Student,因为当前面对象是后面类的实例或者子类的实例时候都会返回true,应该使用obj.getClass()==Student.class判断

四、Try…catch 相对消耗性能比较严重,尽量减少使用频率,使用中尽量扩大作用范围,禁止出现在循环等操作中。

五、创建类似数组等可以设定大小的对象,应尽可能指定大小,最大限度减少内存空间的浪费。

六、HashMap 的读取遍历使用 entry,而不是先取 key 集合,再取值。

七、在方法中创建的对象最好在使用完毕后将引用指向 null,利于 GC 垃圾回收。

八、数组复制使用 system.arraycopy(),减少使用创建新数组赋值的方法。

九、方法大小不要超过80行,方法栈太深容易导致内存溢出;尽量不要出现功能太少的类,类的维护也需要性能开销。

十、创建复杂对象应使用clone方法,减少构造方法调用的开销。

小结

未完待续……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: