使用私有静态方法

41
你认为使用 私有静态方法 怎么样?
就我个人而言,只要不需要访问任何实例字段,我更喜欢使用 静态 私有方法而不是非静态方法。
但是我听说这种做法违反了面向对象编程(OOP)的原则。
编辑:我想知道的是从样式角度而言,而不是性能。

谢谢。我找不到它。 - Andrey Vityuk
7个回答

44

一个private static方法本身并不违反面向对象编程,但是如果一个类中有很多这样的方法,它们不需要(也无法)访问实例字段,那么你就不是在面向对象编程,因为“对象”意味着定义了状态和对该状态的操作。如果它们不需要任何状态,为什么要将这些方法放在该类中呢?

(*) = 原则上,由于Java中的类级可见性,一个类的静态方法可以访问该类的对象的实例字段,例如:

class Test
{
  int field = 123;

  private static void accessInstance(Test test)
  {
    System.out.println(test.field);
  }
}

当然,你需要自己传入实例的引用(this指针),但这样你基本上就是在模仿实例方法了。我提到这一点只是为了完整性。


好的观点。包含静态方法的一个反驳理由是为了内聚性,但如果你有太多的话,可能表明该类已经超出了其意图。 - Aram Kocharyan

22
如上所述,私有静态方法通常用于组织重复使用的逻辑并减少/消除重复代码。我惊讶地发现在这个讨论中没有提到性能方面。来自Renaud Waldura的"The Final Word on Final":

(请注意,私有静态方法隐含地是final的)

“由于final方法仅在声明类中实现,因此没有必要动态分派对final方法的调用,并且可以使用静态调用。编译器可以发出对该方法的直接调用,完全绕过通常的虚拟方法调用过程。因此,final方法也是即时编译器或类似优化工具内联的候选方法。(请记住,私有/静态方法已经是final了,因此始终被考虑为此优化。) ”

查看整篇文章:http://renaud.waldura.com/doc/java/final-keyword.shtml


4

无论是私有还是公共的,静态方法都没问题,但如果你发现自己一直在使用它们(当然,那些不访问任何实例字段的实例方法基本上是为此目的而设计的静态方法),那么你可能需要重新考虑设计。虽然这并非总是可能的,但大多数情况下,方法应该与其操作的数据一起存在 - 这是面向对象编程的基本思想。


3

我并不认为你所做的有任何实质性问题,但我的第一个问题是:如果该方法不需要访问任何实例字段,那么它首先为什么要存在于该类中呢?


这种情况可能会发生在我需要对某些公共方法的输入参数应用特定检查时,例如某种小型辅助方法。 - Andrey Vityuk
...或者当你处理静态字段时,显然 =8-) - Yuval
@Andrey - 这非常有道理。就像我说的,如果我发现自己在做同样的事情,这只是我会问自己的第一个问题。通常那些“辅助”方法可以用于其他事情,并且更好地重构到另一个类中。但是,有时它们也不是最好的选择 :) - Eric Petroelje
我猜常见的答案是“我正在使用一种不允许自由函数的语言”。 - D.Shawley
1
如果你将它们设为包私有,你也可以对它们进行单元测试。 - Tom Hawtin - tackline
@Eric - 是的,它们经常被提取到某个实用类中 :) - Andrey Vityuk

0

这是个人口味问题,但我通常会让不依赖对象内状态的方法为静态方法。这样,如果需要相似功能的静态函数,我就不必重写代码。排序函数就是一个很好的例子。


0

我不太喜欢使用私有静态方法。我会使用公共静态方法,并将它们分组到Util类中以促进重用。


1
你曾经如何处理那些过于特定而无法共享的方法?对于一些通用功能,我也会将方法提取到实用类中。 - Andrey Vityuk
4
别随意地随意分组方法。 - Tom Hawtin - tackline

0

私有静态方法可以操作其类的私有静态成员,这可用于封装和统一某些特定类操作。

使用静态方法的主要缺点在于丧失了覆盖的可能性。由于Java中的类不像Smalltalk中的类那样,您无法覆盖静态方法。

由于您的问题涉及私有静态方法,因此无论如何都不能进行覆盖。

我倾向于仅在实用程序类(例如java.lang.Math)或单例模式等模式的情况下使用静态方法。所有这些都需要比private更高的可见性,因为它们代表其类向其他人提供的服务。

最后思考:如果您有一个或多个私有静态方法,请考虑将它们提取到专用实用程序类中并使它们公开。更好的方式是将它们作为实例方法,并使用单例模式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接