【前言】欢迎订阅【解读《Effective Java》】系列专栏
《Effective Java》是 Java 开发领域的经典著作,作者 Joshua Bloch 以丰富的经验和深入的知识,全面探讨了 Java 编程中的最佳实践。这本书被公认为 Java 开发者的必读经典,对提升编码技巧和代码质量具有重要意义。
在《Effective Java》中,Bloch 总结了 Java 编程的精髓,涵盖了从对象创建和销毁,到类和接口设计,再到泛型、枚举和并发编程的方方面面。每一条法则不仅是对具体问题的解决方案,更是经验的凝练,旨在帮助开发者编写更高效、可维护且健壮的代码。
为了帮助大家更好地理解和应用这些编程原则,我们推出了【解读《Effective Java》】系列专栏。在这里,我们将逐条解读《Effective Java》第三版中的90条编程法则。每篇文章将详细总结和分析法则,结合实际代码示例和应用场景,帮助您将理论知识转化为实际编程能力。
适合人群:
- Java 初学者:掌握 Java 编程的核心原则和最佳实践。
- 中级开发者:获取深入见解和高级技巧,提升编码能力。
- 资深工程师:优化和重构现有代码,提升开发效率。
敬请关注我们的专栏,与我们一起深入探索 Java 编程的精髓,提升您的编码技能。感谢您的订阅与支持,我们期待与您共同踏上这段充满知识和启发的编程之旅!
感谢您的订阅:解读《Effective Java》
博主公众号:
java.lang.Math 类的设计
《Effective Java》第三版中的第4条是“通过私有构造器强化不可实例化的能力”。其主要目的是防止类被实例化,从而保证该类只能用于提供静态方法或字段。这个设计模式常用于工具类,比如 java.lang.Math
类,因为这些类的实例化没有实际意义,同时避免潜在的错误和不必要的资源开销。
以 java.lang.Math
类为例,Math
类是一个工具类,类中的方法,例如 sqrt()
, pow()
, max()
等,都是静态方法。这意味着它们可以直接通过类名访问,而无需创建类的实例。例如:
double result = Math.sqrt(16.0);
这些静态方法提供了类的所有功能,不需要实例化类来调用它们,所以 Math
类的实例化没有任何意义,这也是 Math
类的设计目的:提供工具方法而非对象实例。
为了确保 Math
类不能被实例化,Java 标准库的设计者遵循了以下实践:
public final class Math {
// Don't let anyone instantiate this class.
private Math() {}
// Static methods
public static double sqrt(double a) {
// Implementation
}
// Other methods...
}
public final class
:Math
类被声明为 final
,这意味着它不能被继承。这个设计防止了其他类对 Math
类进行扩展,从而保持了类的完整性。
在 Java 中,当类不包含显式的构造器时,编译器会生成默认的空参构造器,因此我们需要提供一个默认的空参构造器,并声明为 private
,使得外部无法访问,该类也就无法被实例化:
private Math() {}
为了防止有人使用不正当的方式尝试实例化 Math
类,我们可以在私有构造器中抛出 AssertionError
异常,这样当调用构造器进行实例化时调用者就会收到明确的错误信息:
private Math() {
throw new AssertionError("Cannot instantiate Math");
}
除了抛出异常,我们还可以添加类似的醒目注释:Don't let anyone instantiate this class.
,向使用者提醒该类的设计意图:
// Don't let anyone instantiate this class.
private Math() {}
经验总结
因此,当我们需要设计一个仅用于提供工具方法的工具类时,可以参考java.lang.Math
类,尝试使用静态方法提供类的所有功能,这样不需要通过实例化来调用;再将构造器设置为 private
,防止类的无效实例化,还避免了资源浪费和潜在的设计错误。