是否强制实用程序 class 应该是最终的私有构造函数?
Is it mandatory utility class should be final and private constructor?
通过构造私有构造函数,我们可以避免从外部的任何地方实例化class。并且通过使 class 最终化,没有其他 class 可以扩展它。为什么 Util class 需要有 private
构造函数和 final
class ?
没有必要,但是很方便。实用程序 class 只是相关函数的命名空间持有者,并不意味着被实例化或子classed。因此,防止实例化和扩展会向 class.
的用户发送正确的消息
默认情况下,这种 class 通常用于聚合执行不同 this 的函数,在这种情况下我们不需要创建新对象
从功能或java复杂性或运行时的角度来看,这不是强制要求。然而,它的编码标准被更广泛的社区所接受。甚至许多静态代码审查工具,如 checkstyle 和许多其他工具,都会检查 class 是否遵循了此约定。
为什么遵循这个约定,已经在其他答案中解释过,甚至 OP 也涵盖了这一点。
我想进一步解释一下,大多数 Utility classes 都有 methods/functions,它们独立于对象实例。这些是聚合 functions.As 它们仅取决于 return 值的参数,而不与实用程序 class 的 class 变量相关联。所以,这些 functions/methods 大部分都保持静态。因此,Utility classes 是理想的 classes with all the static methods。
所以,任何调用这些方法的程序员都不需要实例化这个class。然而,一些机器人编码器(可能经验或兴趣较少)将倾向于在调用其方法之前创建他们认为需要的对象。为了避免创建对象,我们有 3 个选项:-
继续教育人们不要实例化它。 (再正常不过的人也做不下去。)
- 将 class 标记为摘要 :-
现在机器人编码器不会再创建对象。但是,评论和更广泛的 java 社区会争辩说,标记摘要意味着您希望有人对其进行扩展。所以,这也不是一个好的选择。
- 私有构造函数:-
Protected 将再次允许子 class 创建对象。
现在,如果有人想为这些实用程序的某些功能添加新方法 class,他不需要扩展它,他可以添加新方法,因为每个方法都是独立的,没有机会破坏其他功能。因此,无需覆盖它。而且你不会实例化,所以需要 subclass 它。最好将其标记为最终版本。
总而言之,创建实用程序对象 classes 没有意义。因此构造函数应该是私有的。而且您永远不想覆盖它,因此将其标记为最终。
Java 语言和 Java 运行时之间有一个重要的区别。
javaclass编译成字节码时,没有访问限制的概念,public
、package
、protected
、private
是等价的。总是可以通过反射或字节码操作来调用 private
构造函数,因此 jvm 不能依赖这种能力。
另一方面,final
是贯穿字节码的东西,它提供的保证可以被 javac 用来生成更高效的字节码,并被 jvm 用来生成更高效的机器指令。
此启用的大多数优化不再相关,因为 jvm 现在将相同的优化应用到所有 class在运行时是单态的 es — 而这些总是最重要的。
通过构造私有构造函数,我们可以避免从外部的任何地方实例化class。并且通过使 class 最终化,没有其他 class 可以扩展它。为什么 Util class 需要有 private
构造函数和 final
class ?
没有必要,但是很方便。实用程序 class 只是相关函数的命名空间持有者,并不意味着被实例化或子classed。因此,防止实例化和扩展会向 class.
的用户发送正确的消息默认情况下,这种 class 通常用于聚合执行不同 this 的函数,在这种情况下我们不需要创建新对象
从功能或java复杂性或运行时的角度来看,这不是强制要求。然而,它的编码标准被更广泛的社区所接受。甚至许多静态代码审查工具,如 checkstyle 和许多其他工具,都会检查 class 是否遵循了此约定。
为什么遵循这个约定,已经在其他答案中解释过,甚至 OP 也涵盖了这一点。
我想进一步解释一下,大多数 Utility classes 都有 methods/functions,它们独立于对象实例。这些是聚合 functions.As 它们仅取决于 return 值的参数,而不与实用程序 class 的 class 变量相关联。所以,这些 functions/methods 大部分都保持静态。因此,Utility classes 是理想的 classes with all the static methods。 所以,任何调用这些方法的程序员都不需要实例化这个class。然而,一些机器人编码器(可能经验或兴趣较少)将倾向于在调用其方法之前创建他们认为需要的对象。为了避免创建对象,我们有 3 个选项:-
继续教育人们不要实例化它。 (再正常不过的人也做不下去。)- 将 class 标记为摘要 :- 现在机器人编码器不会再创建对象。但是,评论和更广泛的 java 社区会争辩说,标记摘要意味着您希望有人对其进行扩展。所以,这也不是一个好的选择。
- 私有构造函数:- Protected 将再次允许子 class 创建对象。
现在,如果有人想为这些实用程序的某些功能添加新方法 class,他不需要扩展它,他可以添加新方法,因为每个方法都是独立的,没有机会破坏其他功能。因此,无需覆盖它。而且你不会实例化,所以需要 subclass 它。最好将其标记为最终版本。
总而言之,创建实用程序对象 classes 没有意义。因此构造函数应该是私有的。而且您永远不想覆盖它,因此将其标记为最终。
Java 语言和 Java 运行时之间有一个重要的区别。
javaclass编译成字节码时,没有访问限制的概念,public
、package
、protected
、private
是等价的。总是可以通过反射或字节码操作来调用 private
构造函数,因此 jvm 不能依赖这种能力。
final
是贯穿字节码的东西,它提供的保证可以被 javac 用来生成更高效的字节码,并被 jvm 用来生成更高效的机器指令。
此启用的大多数优化不再相关,因为 jvm 现在将相同的优化应用到所有 class在运行时是单态的 es — 而这些总是最重要的。