Java:何时使用静态方法

问题

我想知道何时使用静态方法?假如我有一个带有一些 getter 和 setter 的类,一个或两个方法,我希望这些方法只能在类的实例对象上调用。这是否意味着我应该使用静态方法?

例如

Obj x = new Obj();
x.someMethod

要么

Obj.someMethod

(这是静态方式吗?)

我很困惑!


#1 热门回答(1159 赞)

一个经验法则:问问自己“即使没有构建Obj,这个方法也有意义吗?”如果是这样,那肯定是静态的。

因此在类 Car 中你可能有一个方法double convertMpgToKpl(double mpg)这将是静态的,因为人们可能想知道35mpg转换成什么,即使没有人建造过汽车。但是void setMileage(double mpg)(设置一个特定Car的效率)不能是静态的,因为在构造任何Car之前调用该方法是不可思议的。

(顺便说一下,反过来并不总是这样:你有时会有一个涉及两个Car对象的方法,但仍然希望它是静态的。例如Car theMoreEfficientOf(Car c1,Car c2)。虽然这可能是转换为非静态版本,有人会争辩说,由于没有“特权”选择哪个Car更重要,你不应该强迫调用者选择一个Car作为你将调用方法的对象但是,这种情况只占所有静态方法的一小部分。)


#2 热门回答(452 赞)

仅在以下方案中定义静态方法:

  • 如果你正在编写实用程序类,则不应更改它们。
  • 如果方法未使用任何实例变量。
  • 如果任何操作不依赖于实例创建。
  • 如果有一些代码可以被所有实例方法轻松共享,请将该代码提取到静态方法中。
  • 如果你确定永远不会更改或覆盖方法的定义。由于静态方法无法被覆盖。

#3 热门回答(136 赞)

使用静态方法有一些正当理由:

  • 性能:如果你想要运行某些代码,并且不想实例化额外的对象,请将其推送到静态方法中。 JVM也可以很好地优化静态方法(我想我曾经读过James Gosling声明你不需要JVM中的自定义指令,因为静态方法会同样快,但找不到源 - 因此它可能是完全错误的)。是的,它是微优化,可能不需要。而且我们程序员从不做不需要的东西只是因为它们很酷,对吧?
  • 实用性:不是调用新的Util().method(arg),而是使用静态导入调用 Util.method(arg) 或方法(arg)。更简单,更短。
  • 添加方法:你真的希望类String有一个removeSpecialChars()实例方法,但它不存在(它不应该,因为你的项目的特殊字符可能与其他项目不同),你不能添加它(因为Java有点理智),所以你创建了一个实用程序类,并调用removeSpecialChars(s)而不是s.removeSpecialChars()。甜。
  • 纯度:采取一些预防措施,你的静态方法将是一个纯函数,也就是说,它唯一依赖的是它的参数。数据输入,数据输出。这更容易阅读和调试,因为你没有担心继承怪癖。你也可以使用实例方法来完成它,但编译器将使用静态方法帮助你(通过不允许引用实例属性,重写方法等)。

如果你想制作单例,你还必须创建一个静态方法,但是......不要。我的意思是,三思而后行。

现在,更重要的是,为什么你不想创建静态方法?基本上,多态性将无法在静态方法中体现。你将无法覆盖该方法,也无法在接口(Java 8之前)中声明它。它从你的设计中获得了很大的灵活性。此外,如果你需要state,如果你不小心,最终会出现大量的并发错误和/或瓶颈。