java中静态类的模拟

时间:2009-08-07 07:15:25

标签: java

您如何看待以下模拟java中的静态类的方法? 您可以添加非静态方法,但无法调用它们。

 /**
  * Utility class: this class contains only static methods and behaves as a static class.
  */
 // ... prevent instantiation with abstract keyword
 public abstract class Utilities
    {
        // ... prevent inheritance with private constructor
        private Utilities() {}

        // ... all your static methods here
        public static Person convert(String foo) {...}
    }

7 个答案:

答案 0 :(得分:8)

这是通常的方式。但是,不需要 abstract 关键字。使用私有构造函数就足够了,因为

  • 它阻止了对象的创建(来自课外)
  • 它阻止了继承

abstract 关键字向用户建议该类的用户可以实现该类,而不是这里的情况。

答案 1 :(得分:5)

Effective Java中的

第4项(一本非常有效的书)说:

// Noninstantiable utility class
public final class Utility {

    private Utility() {
        throw new AssertionError();
    }
}

因为显式的costructor是私有的:

  • 你无法实例化
  • 你不能扩展它(好像它被宣布为最终)

AssertionError不是必需的,但它提供了另一个小的好处:它可以防止在类中意外调用costructior。

你也可以创建一个特定的注释,比如@BagOfFunction,并注释你的类:

@BagOfFunctions
public final class Utility {

    private Utility() {
        throw new AssertionError();
    }
}

基本上你交换一个自我记录注释的评论。

答案 2 :(得分:3)

我的FindBugs插件建议使用final类而不是抽象类。我在我的项目中使用它。如果它成为FindBugs检查的规则,它似乎是一种普遍的习惯用法。

答案 3 :(得分:2)

我会说,如果你已经是一个私人构造函数

  

private Utilities(){}

抽象关键字不是必需的。而是让它成为最终的。

对于任何实际的手段来说,你的版本的差异是微不足道的。

答案 4 :(得分:2)

我更喜欢制作此类final,而不是abstract。虽然这只是个人风格的问题。

顺便说一句,我想如果你放一些能量,仍然可以调用它的实例方法。例如。可以尝试使用objenesis来创建类的实例。

答案 5 :(得分:2)

我必须同意上述内容。使用“final”而不是“abstract”。请记住,像“最终”和“抽象”这样的词语也是与其他程序员交流的一种方式,因为它们是对机器的指令。摘要意味着后来会有后代类,而最终意味着你不会通过重构来看到这个类的后代(这是你的意图)。

此外,在我见过的大多数标准中,并且始终在我的公司中,最好的做法是使抽象类使某些特别保持未使用状态,另存为其他类的父类。 。 “抽象”被视为“蓝图”或“一般结构”,你永远不会驾驶“抽象”汽车。另一方面,最终的类是永久实例化的,尤其是工厂模式。

答案 6 :(得分:1)

我的建议是:通过放置javadocs来防止错误使用(即实例化)

这不是更简单吗?我认为你的队友能够阅读;)