【问题标题】:Java: Static Class?Java:静态类?
【发布时间】:2010-12-23 02:16:58
【问题描述】:

我有一个充满实用功能的类。实例化它的实例没有语义意义,但我仍然想调用它的方法。处理这个问题的最佳方法是什么?静态类?摘要?

【问题讨论】:

  • 顺便说一句,你不能让顶级类静态...

标签: java class oop static utility


【解决方案1】:

标记为 final 的类上的私有构造函数和静态方法。

【讨论】:

  • @matt b:正如 David Robles 在他的回答中指出的那样,你不需要使类成为最终的......它不能被子类化,因为子类将无法调用超类构造函数,因为它是私人的。但是...明确表示没有害处。但是 jfyi :-)。
【解决方案2】:

将类声明为static 毫无意义。只需声明它的方法 static 并像往常一样从类名中调用它们,就像 Java 的 Math 类一样。

此外,尽管将构造函数设为私有并不是绝对必要的,但这样做是个好主意。将构造函数标记为私有可防止其他人创建您的类的实例,然后从这些实例调用静态方法。 (这些调用在 Java 中的工作方式完全相同,它们只会误导并损害代码的可读性。)

【讨论】:

  • 另外,不要忘记创建一个私有构造函数。
  • @Asaph:同意。我在答案中添加了一些内容。谢谢。
  • 如果你想要一个内部类中的静态方法,这个类也必须是静态的。
【解决方案3】:

根据大书"Effective Java"

第 4 项:使用私有构造函数强制实现不可实例化

- 试图通过抽象类来强制执行不可实例化是行不通的。

- 仅当类不包含显式构造函数时才会生成默认构造函数,因此可以通过包含私有构造函数使类不可实例化:

// Noninstantiable utility class
public class UtilityClass
{
    // Suppress default constructor for noninstantiability
    private UtilityClass() {
        throw new AssertionError();
    }
}

因为显式构造函数是私有的,所以在类之外是不可访问的。 AssertionError 不是严格要求的,但它提供了保险,以防意外从类中调用构造函数。它保证类在任何情况下都不会被实例化。这个习语有点违反直觉,因为构造函数是明确提供的,因此无法调用它。因此,如上所示,包含注释是明智的。

作为一个副作用,这个习语还可以防止类被子类化。所有构造函数都必须显式或隐式调用超类构造函数,并且子类将没有可访问的超类构造函数来调用。

【讨论】:

  • 您为什么选择AssertionError 而不是IllegalStateExceptionUnsupportedOperationException 等其他替代方案?
  • @Pacerier 见this
  • @bcsb1001,这将我们带到this
【解决方案4】:

只是为了逆流而上,静态成员和类不参与 OO,因此是邪恶的。不,不是邪恶的,但说真的,我会推荐一个带有单例模式的普通类来访问。这样,如果您在以后的任何情况下都需要覆盖行为,那么这不是重大的重组。 OO 是你的朋友 :-)

我的 $.02

【讨论】:

  • 单身人士也被认为是邪恶的。
  • 您使用私有构造函数来防止任何人实例化或子类化该类。请参阅 David Robles 的回答:stackoverflow.com/questions/1844355/java-static-class/…
  • 单例并不比依赖注入更邪恶:)
  • OO 有它的位置,但有时它只是不实用,或者会浪费资源——例如,像 Math.abs() 这样简单的东西。没有理由仅仅为了实例化一个对象而实例化一个对象,而静态方法调用也可以为您服务,而无需任何 O-O-开销。 ;)
  • @rob re OO,我同意,Math.Abs​​ 可能永远不需要实例。当我听到“我有一个实用程序类”时,我看到了 Math.Avg(),您现在需要在其中添加对加权平均值的支持。我看到需要重构以支持 href 或仅 url 等的 Url 生成器、param in、url out 等。由于这些原因,拥有基于 OO 的实用程序类可以得到回报。另外,现在我将放弃标准的OO防御战术,测试! /我鸭子
【解决方案5】:

评论“私有构造函数”参数:来吧,开发者没那么傻;但他们很懒惰。创建一个对象然后调用静态方法?不会发生的。

不要花太多时间来确保你的课程不会被滥用。对你的同事有一些信心。无论您如何保护它,总有一种方法可以滥用您的课程。唯一不能被滥用的是完全没用的东西。

【讨论】:

  • 一个见过(在生产代码中,而不是在学生代码中)object.staticMethod 我认为你高估了 Joe Random Programmer 的能力! :-P
【解决方案6】:
  • 最终类和私有构造函数(很好但不是必需的)
  • 公共静态方法

【讨论】:

    【解决方案7】:

    听起来您有一个类似于java.lang.Math 的实用程序类。
    那里的方法是带有私有构造函数和静态方法的最终类。

    但要注意这对可测试性有什么影响,我建议阅读这篇文章
    Static Methods are Death to Testability

    【讨论】:

    【解决方案8】:

    您可以使用来自 lombok https://projectlombok.org/features/experimental/UtilityClass 的 @UtilityClass 注解

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-02
      • 2011-11-21
      • 2016-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多