欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

三、编写高质量的代码—类、对象和方法(笔记)

程序员文章站 2022-06-16 16:17:41
...

 

本博文为《编写高质量代码—改善Java程序的151个建议》一书的阅读笔记。该书从很多方面给予了编写高质量代码的宝贵经验。而且该书应该是那种开发经验越丰富,体会越深的书籍。在阅读过程中,从该书中收获良多,这里主要作下书籍笔记,有体会的地方加点自己的想法。受限于知识水平,部分内容还没能深刻体会,所以更多更好的内容和具体实例还需要从书中去找寻。

一、静态方法不能覆写可以隐藏

在Java中可以通过覆写(Override)来增强或减弱父类的方法和行为,但覆写是针对非静态方法(也叫做实例方法,只有生成实例才能调用的方法)的,不能针对静态方法(static修饰的方法,也叫类方法)。
如果在了类中构建与父类相同的方法名、输入参数、输出参数、访问权限(权限可以扩大)并且父类子类都是静态方法,此种行为叫做隐藏。与覆写有两点不同:
1. 表现形式不同:隐藏用于静态方法,覆写用于非静态方法。在代码的表现上是:@Override注解可以用于覆写,不能用于隐藏。
2. 职责不同:隐藏的目的是为了抛弃父类静态方法。
所以在静态方法调用时一定要注意避免使用实例对象访问静态方法或静态属性,而应该使用类进行访问。

二、构造函数尽量简化

书中举了一个非常好的例子,这里限于篇幅不搬上来了。总之构造函数如果过于复杂,可能导致由于类的构造顺序问题出现意想不到的结果。因此在类初始化时如果有什么复杂逻辑可以考虑抽出单独的init或start方法,尽量保证构造函数的简化。

三、避免在构造函数中初始化其它类

在构造函数中初始化其它类可能导致在复杂项目中出现类对象循环构造的情况,所以需要尽量避免。

四、使用构造代码块精炼程序

构造代码块是指在类中没有任何的前缀或后缀,并使用“{}”括起来的代码片段。例如

public class Child {
	{
		System.out.println("这是构造代码块");
	}

	public Child() {
		System.out.println("这是无参构造函数");
	}
}

 编译器会把构造代码块插入到每个构造函数的最前端,所以在生成对象时总是会先执行构造代码块,再执行构造函数的代码。(不过有一种情况例外,遇到this关键字时,即构造函数中调用其它构造函数时,此方法不会插入构造代码块)
构造代码块主要适用于如下场景:(1)初始化实例变量;(2)初始化实例环境。

五、覆写equals方法要注意

关于覆盖equals方法的中肯建议,《Effective Java》一书中给了非常好的建议。首先equals方法实现了等价关系,需要满足自反性、对称性、传递性、一致性。
编写高质量equals方法的诀窍为:
1. 使用==操作符检查“参数是否为这个对象的引用”,如果是,则返回true;
2. 使用instanceof操作符检查“参数是否为正确的类型”,如果不是,则返回false;
3. 把参数转化为正确的类型;
4. 对于该类中的每个“关键域”,检查参数中的域是否与该对象中对应的域相匹配;
5. 编写单元测试查看是否满足对称性、传递性、一致性;
6. 覆写equals方法总要覆盖hashCode方法;
7. 不要将equals声明中的Object对象声替换成其他的类型。
equals方法可以通过IDE(例如eclipse)自动进行生成,避免不必要的错误。

六、覆写equals方法必须覆盖hashCode方法

如果覆写了equals方法而没有覆写hashCode方法,则违背了Object.hashCode的通用约定,从而导致该类无法结合所有基于散列的集合一起正常运行。
关于HashCode的写法《Effective Java》中有详细的建议,在实际编写中可以使用IDE(例如eclipse)自动生成,或者使用Commons-lang包中的HashCodeBuilder类进行生成。

七、推荐覆写toString方法

由于JDK提供的默认toString方法并不友好,所以为了打印的内容便于理解,推荐覆写toString方法。

八、不要主动进行垃圾回收 

如果不是对于JVM非常了解,不要在代码中主动进行垃圾回收,这样可能导致极大的项目风险。