【问题标题】:When is using public fields acceptable?什么时候可以使用公共字段?
【发布时间】:2014-06-06 05:48:09
【问题描述】:

我有一个主类,它有一个线程池,很多其他类都使用它来对数据库执行操作。我目前有一个 getter 方法来获取池,它工作正常,但似乎有点笨拙。

在任何情况下可以接受使用公共字段而不是 getter/setter 方法吗?

【问题讨论】:

  • final 常量例如不需要 setter & getter
  • 如果您愿意并且没有规范可以阻止它。公共字段本身没有任何问题,只是不建议您是否打算生成一个不能通过使用与您的意图相反的接口来破坏的“安全”API。
  • 老实说,我认为这是一个基于意见的问题。是否使用 public 修饰符实际上取决于您和您的开发团队。如果您正在编写一个旨在供公众使用的库,那么您需要避免向公众提供对可以更改对象状态的字段的访问权限。如果这是只能在内部使用的东西,那么这取决于您的开发团队。您应该记录更改公共字段的值可能会产生奇怪的效果,因此只有在您知道自己在做什么的情况下才这样做。
  • 我认为更好的选择可能是使用包级别修饰符(即无修饰符),以便只有此包中的类可以直接访问。

标签: java public


【解决方案1】:

使用 getter 和 setter 代替公共字段的原因有很多。我在 SO 中找到的一个是

因为从现在起 2 周(几个月、几年)后,当您意识到您的 setter 需要做的不仅仅是设置值,你也会意识到 该属性已在 238 个其他类中直接使用:-)

您还可以查看this post,它还引用了我在上面给出的内容并提供了一些其他示例。阅读,然后您可以决定是否在您的案例中使用公共字段。

【讨论】:

  • 但实际上发生这种情况的可能性非常低。
  • 是的,我知道,所以我说是否使用公共字段由开发者决定。
  • 对于诸如字符串之类的东西,封装它们是有意义的,但对于像线程池这样的东西,做类似 someInstance.getThreadPool().execute( ...) 当你可以做 someClass.threadPool.execute(...).
  • 如果您有一个返回 ThreadPool 对象的 getter 方法,那么您已经几乎获得了对该对象的公共访问权限:他们无法使用 getter 方法覆盖该对象,但是他们可以修改对象(通过调用它的方法)。让对象执行someInstance 的线程可能更合适,即有一个诸如executeInstance(Object someInstance) 之类的方法,然后此方法代表参数使用内部线程池执行。
【解决方案2】:

让您的类字段保持私有并使用 getter/setter 方法提供了一个抽象层,并且从长远来看更易于维护。看到这个:What's the deal with Java's public fields?

【讨论】:

    【解决方案3】:

    在任何情况下可以接受使用公共字段而不是 getter/setter 方法吗?

    公共字段不好的主要原因是它们将实现暴露给外界。这会导致不必要的耦合;即过度依赖其他类的实现细节的类。这往往会使代码更难理解和更难改变。如果该字段不是final,您需要搜索整个代码库以确定没有“干扰”该字段。 (好的,IDE 让这变得更容易......但是将公共字段与没有设置器的私有字段进行对比。)

    次要原因是您无法覆盖字段。一旦您在超类中公开了一个字段,您就无法在子类中做任何事情来修改或限制其含义。 (相比之下,getter 和 setter 可以被覆盖......)

    唯一可以接受(从风格角度)具有“公共”字段的情况是声明字段的类是私有嵌套类或内部类。结果是该字段的所有依赖项都限制在包含声明的源文件中......这否定了上述问题。

    更新 - 我忘了public static final ...但我们往往根本不认为这些是字段。无论如何,直接访问public static final 字段是正常的做法。常量的想法是故意公开名称、类型和值......并且由于静态字段的性质,覆盖问题不适用。


    我目前有一个 getter 方法来获取池,它工作正常,但似乎有点笨拙。

    “笨拙”是见仁见智/品味的问题。就个人而言,我认为obj.getInstance()obj.instance 相比并不笨拙。这只是 Java 方式1.

    另一方面,如果您没有 getInstance() 方法,则使用池的所有类都必须具有对 instance 字段的硬编码引用。如果(由于某些原因)您需要更改访问池的方式(例如,添加安全检查、添加计数器、使池创建变得惰性、确保访问正确同步),那么您必须更改每个和您对字段进行编码引用的每个地方。但是有了吸气剂,你就只有一个地方可以改变了。

    1 - 显然,其他语言的做法不同。但你不是在写那些语言。 Java 就是这样。

    【讨论】:

      猜你喜欢
      • 2011-10-22
      • 2011-02-24
      • 2023-04-02
      • 2011-03-23
      • 2012-07-09
      • 2010-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多