为什么要使用私有静态方法?


68

我只是想解决一个问题。与具有私有可见性的普通方法相比,拥有私有静态方法有什么意义?

我本来以为拥有静态方法的一个优点是可以在没有类实例的情况下调用它,但是由于它的私有性,甚至有一点是静态的吗?

我能想到的唯一原因是,它有助于从概念上理解类级别(而不是对象级别)上的方法。


32
是的,这是有原因的。您的公共/默认静态方法仍然可以调用您的私有静态方法。是否完全应该使用静态方法,以及何时适合使用任何类型的私有方法是单独的问题,因此请注意不要将它们与该问题混在一起。

2
快速示例-内部类使用的工厂方法可防止其他类调用(您必须通过工厂方法来获取该类的实例)。

2
@MattFenwick:您应该将其发布为答案。
Doc Brown

9
通过将方法设为静态,您还可以说它不读取或写入实例变量。不与实例变量交互的方法通常更易于移动和重构到其他位置。
Mark Rogers

1
不要忘记,无论静态方法是私有方法,内部方法还是公共方法,如果没有您自己的特定代码同步工作,它仍然不是线程安全的。
克雷格

Answers:


70

静态的特性与可见性无关。

想要使用静态方法(某些不依赖于非静态成员的代码)的原因仍然有用。但是也许您不希望任何人/其他任何人使用它,而只是您的课堂。


3
我认为您走在正确的道路上,但我也认为您缺少关键点。大多数静态方法的副作用为零(它们是有效的函数,而不是方法)-这就是为什么首先将它们设为静态的原因。反对它们私有的观点是“如果它们没有副作用,为什么不将它们公开以促进代码重用”。关键是:当我们将其设为私有时,通常是因为我们希望您重用使用该私有方法的整个类,而不仅仅是该方法。
corsiKa 2014年

我必须说我从未做到过或从未见过这种行为。我做过几次是为公共静态类提供帮助方法。
Miyamoto Akira

1
@corsiKa:副作用不是问题。使类的静态成员成为非私有有效地保证了该类的每个未来版本都将包含相同名称的相同方法,并且该方法执行相同的操作。如果需求发生变化,并且该类的未来版本可能不需要一种与当前类完全相同的方法,则可以安全地将私有方法替换为更好地满足该类新需求的方法。作为一个简单的例子,假设一个类需要一个方法,该方法需要一个字符串并执行类似<to的替换&lt;,等等。在编写时……
supercat 2014年

1
...已知它所传递的字符串不包含任何“&”号,因此它不会转换&&amp;[我正在编写代码,即使我没想到它是必需的,我也将转换&&amp;它没有]。它后来成为必要处理&号,但该方法是公共的,改变它扩大&&amp;能够打破它执行自己的代码外&至- &amp;替代。但是,如果该方法是私有的,则可以固定该方法以进行处理,&而不会导致任何外部代码出现问题。
2014年

这是一个有趣的问题,至少可以说,但我看不出它如何为静态使得任何更多的问题比不是静态的,这是关键,这个问题的。如果我们遵循您的逻辑,那么所有地方都将重新实现所有内容,因为“天哪,如果某天有错误或要求发生变化怎么办?”
corsiKa 2014年

26

一个相当普遍的原因(在Java中)是通过使用一种简单的private static方法来减少构造函数的混乱情况,从而在构造函数中初始化不可变字段变量。

  • 它是private:外部类不应看到它。
  • 它是static:它可以执行一些操作中,独立的1主机类的状态的。

以下是一些人为设计的示例...

例如:

public class MyClass{
    private final String concatenated;

    public MyClass(String a, String b){
        concatenated = concat(a,b);
    }

    public String getConcatenated(){
       return concatenated;
    }

    /**
    *  Concatenates two Strings as `s1---s2`
    **/
    private static final String concat(String s1, String s2){
        return String.format("%s---%s", s1, s2);
    }
}

1 假设它与其他static变量没有相互作用。


15
当您需要将派生(计算)的参数传递给超类的构造函数时,这甚至更有价值。该super(...)调用必须是类的构造函数的第一行,因此您不能声明局部变量来帮助您确定要传递给超级调用的内容。但是,您可以调用(私有)静态方法,该方法使用必要的行数来计算要传递给超级构造函数的值。
Andrzej Doyle'4

请注意,存在静态初始化程序块的可能性
Franz Ebner 2014年

13

方法的常见用例private static是实用程序方法,它是

  1. 仅由该类使用
  2. 独立于该类的内部状态

12

您会看到许多方法中重复了几行代码,因此您决定将它们提取到单个方法中,因为重复的代码并不好。

您将方法设为私有,因为它不是为广泛使用而设计的,并且您不希望无关的代码调用它。(在评论中讨论这一点……)

由于该方法不访问任何实例字段,因此可以将其设为静态,将其设为静态可以使您更容易理解甚至更快。

然后....(也许现在,也许以后,也许永远不会)

一旦方法已经取得了一成不变的,它是明确的,它可以移出之类的,说给一个统一的类。

将其转换为参数之一的实例方法也很容易,通常这就是代码应该在的地方。


我喜欢这个答案,但是您对此有任何最新参考吗?“甚至可能快一点”
Magnilex

@Magnilex,“ this”指针不会传递给静态类方法,因此,它们将比静态实例方法更快,除非编译器检测到实例方法中未使用“ this”(不太可能)。
2015年

2

我可以想到至少两个原因,为什么您需要在类上使用静态私有方法。

1:您的实例有理由调用您不想直接调用的静态方法,可能是因为它在类的所有实例之间共享数据。

2:您的公共静态方法具有不希望直接调用的子例程。该方法仍在没有实例的情况下调用,只是没有直接调用。

当然,“它可以使班级变得有意义”是一个很好的理由。


1

通常,如果我发现自己正在编写私有静态方法,则可以认为这是我应该分别建模的东西。

由于它们不依赖于特定对象实例的状态,因此公共和私有静态方法的集合可以形成具有其自身语义和非静态方法的完全独立的类。

(另一个提示是,如果我发现我有很多静态方法(公共和私有),它们都具有某种类型的公共参数,那么作为该类型的成员可能会更好。)

因此,为回答您的问题,当类提供一组独立于该类实例的相关方法时,将显示私有静态方法。(...并且由于他们是独立的,因此他们在同班同学中可能会更好。)


-1

我可以想到的一个非常简单的示例是,如果要对传递给main函数的输入参数(或某些操作)进行一些处理。因此,在这种情况下,如果处理量很大并且在其他任何地方都不会使用相同的功能,那么拥有私有功能将是有意义的,因为它将不会在其他任何地方使用/调用+ static,因为main是静态的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.