java 在什么情况下静态方法是一种好的做法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1530353/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 16:56:44  来源:igfitidea点击:

In what situations is static method a good practice?

javastaticmethods

提问by Winston Chen

I have read the following discussions:

我已阅读以下讨论:

Should private helper methods be static if they can be static, and
Should all methods be static if their class has no member variables

如果私有辅助方法可以是静态的它们应该是静态的,如果它们的类没有成员变量
所有的方法都应该是静态的

It seems that people in general would accept static methods, but are a little bit skeptical about it, for the following 2 reasons:

似乎人们一般会接受静态方法,但对其有点怀疑,原因如下:

  1. They are hard to test.
  2. They violate the OO principle. (They are functions, not methods, said a person.)
  1. 它们很难测试。
  2. 它们违反了面向对象原则。(有人说,它们是函数,而不是方法。)

And the most acceptable static methods are private staticones. But then why do static methods exist at all, and in what situations they are the first priority to be adopted?

最可接受的静态方法是私有静态方法。那么为什么静态方法会存在,在什么情况下它们是优先采用的呢?

回答by Jon Skeet

Static methods aren't hard to test in and of themselves. The problem is that other code callingthe static method is hard to test, because you can't replace the static methods.

静态方法本身并不难测试。问题是调用静态方法的其他代码很难测试,因为您无法替换静态方法。

I think static methods are fine either when they're private orwhen they're "utility" methods - e.g. to do string escaping. The problem comes when you use static methods for things that you want to be able to mock out or otherwise replace within tests. Factory methods canbe useful too, although dependency injection is generally a better approach - again, it partly depends on whether you want to be able to replace the functionality in tests.

我认为静态方法在私有“实用”方法时都很好- 例如进行字符串转义。当您对想要在测试中模拟或以其他方式替换的事物使用静态方法时,问题就出现了。工厂方法很有用,尽管依赖注入通常是一种更好的方法 - 同样,这部分取决于您是否希望能够替换测试中的功能。

As for not being "OO" - not everything you write in a generally OO language has to be "pure" OO. Sometimes the non-OO route is simply more pragmatic and leads to simpler code. Eric Lippert has a great blog post about this, which unfortunately I can't find right now. However, there's a comment in this postwhich is relevant. It talks about extension methods rather than static methods, but the principle is the same.

至于不是“面向对象”——并不是你用一般面向对象语言编写的所有东西都必须是“纯”面向对象的。有时,非 OO 路线更实用,并导致代码更简单。Eric Lippert 有一篇关于此的很棒的博客文章,不幸的是我现在找不到。但是,这篇文章中有一条相关的评论。它谈论的是扩展方法而不是静态方法,但原理是相同的。

Extension methods are often criticized as being "not OOP enough". This seems to me to be putting the cart in front of the horse. The purpose of OOP is to provide guidelines for the structuring of large software projects written by teams of people who do not need to know the internal details of each other's work in order to be productive. The purpose of C# is to be a useful programming language that enables our customers to be productive on our platforms. Clearly OOP is both useful and popular, and we've therefore tried to make it easy to program in an OOP style in C#. But the purpose of C# is not "to be an OOP language". We evaluate features based on whether they are useful to our customers, not based on whether they conform strictly to some abstract academic ideal of what makes a language object-oriented. We'll happily take ideas from oo, functional, procedural, imperative, declarative, whatever, so long as we can make a consistent, useful product that benefits our customers.

扩展方法经常被批评为“OOP 不够”。在我看来,这似乎是把车放在马的前面。OOP 的目的是为构建大型软件项目提供指导,这些项目由无需了解彼此工作的内部细节即可高效工作的团队编写。C# 的目的是成为一种有用的编程语言,使我们的客户能够在我们的平台上高效工作。显然,OOP 既有用又流行,因此我们试图使在 C# 中以 OOP 风格进行编程变得容易。但是 C# 的目的不是“成为一种 OOP 语言”。我们根据功能是否对我们的客户有用来评估功能,不是基于它们是否严格符合某种抽象的学术理想,即是什么使语言面向对象。我们很乐意从 oo、函数式、程序式、命令式、声明式等等中汲取灵感,只要我们能够制作出一致、有用的产品,让我们的客户受益。

回答by Michael Borgwardt

I'd say that static methods are definitely OK when they are functions, i.e. they don't do any IO, don't have any internal state and only use their parameters to compute their return value.

我会说静态方法在它们是函数时绝对没问题,即它们不做任何 IO,没有任何内部状态并且只使用它们的参数来计算它们的返回值。

I'd also extend this to methods that change the state of their parameters, though if this is done excessively, the static method should properly be an instance method of the parameter class that it mainly operates on.

我还会将此扩展到更改其参数状态的方法,但如果这样做过度,则静态方法应该正确地成为它主要操作的参数类的实例方法。

回答by Spence

Think of this for a moment. In OO coding, every single function call actually looks like this:

想一想。在 OO 编码中,每个函数调用实际上是这样的:

method(object this, object arg1, object arg2)where this is the object you are calling. All it really is is syntax sugar for this. Additionally it allows you to clearly define scope of variables because you have object variables etc.

method(object this, object arg1, object arg2)这是您正在调用的对象。它真正是为此的语法糖。此外,它允许您清楚地定义变量的范围,因为您有对象变量等。

Static methods simply don't have a "this" parameter. Ie you pass variables in and possibly get a result back out. 1.) is the main reason people avoid them, you can't create an interface to a static method (yet) so you can't mock out the static method to test it.

静态方法根本没有“this”参数。即您传入变量并可能返回结果。1.) 是人们避免使用它们的主要原因,你不能创建一个静态方法的接口(还)所以你不能模拟静态方法来测试它。

Secondly OO are procedures functions etc. Static methods make a lot of sense in certain situations, but they can always be made into a method on an object.

其次 OO 是过程函数等。静态方法在某些情况下很有意义,但它们总是可以成为对象上的方法。

Mind you, you couldn't remove this without a hack:

请注意,如果没有 hack,您无法删除它:

static void Main(string[] args)
{
}

The code that starts your application MUST be callable WITHOUT a reference to an object. So they give you flexibility, whether you choose to use them in your scenario will be predicated by your requirements.

启动您的应用程序的代码必须可以在没有对象引用的情况下调用。因此,它们为您提供了灵活性,您是否选择在您的场景中使用它们将取决于您的需求。

回答by Pete Kirkham

Static methods are fine in most situations where the singleton pattern gives too much flexibility.

在单例模式提供太多灵活性的大多数情况下,静态方法都很好。

For example, take a simple utility such as raising a primitive to a power - obviously you never need to have any polymorphism in that. Primitive values are of static type and mathematical operations are well defined and don't change. It's not like you'll ever get the situation of having two differentimplementationsan no way of switching between them without rewriting all your client code.

例如,采用一个简单的实用程序,例如将原语提升为幂 - 显然,您永远不需要任何多态性。原始值是静态类型,数学运算定义明确且不会改变。这并不是说您永远不会遇到拥有两种不同实现的情况,并且在不重写所有客户端代码的情况下无法在它们之间切换。



(irony off )

(讽刺关闭)

Modern JVMs are pretty good at inlining small calls if only one implementation of an interface is loaded. Unless you have profiled your code and know dispatching your utilities to an interface is an overhead, you've no excuse for not making your utility methods into an interfacewhich can be varied if required.

如果只加载一个接口的一个实现,现代 JVM 非常擅长内联小调用。除非您已经分析了您的代码并且知道将您的实用程序分派到一个接口是一种开销,否则您没有理由不将您的实用程序方法放入一个可以根据需要进行更改的接口中。

回答by KLE

I think a definite case for static methods is when you cannot make them dynamic, because you cannot modify the class.

我认为静态方法的一个明确情况是您无法将它们设为动态,因为您无法修改 class

This is typical for JDK objects, and also all objects coming from external libraries, and also primitive types.

对于 JDK 对象以及来自外部库的所有对象以及原始类型都是典型的

回答by akf

Another good scenario for static methods are implementations of the Factory pattern, where you are allowing for instances of a class to be constructed in a specific manner.

静态方法的另一个好场景是工厂模式的实现,您可以在其中以特定方式构造类的实例。

Consider the Calendarclass, which has a set of static getInstancemethods, each returning instances primed with the desired TimeZoneand/or Localeor the default.

考虑一个Calendar类,它有一组静态getInstance方法,每个都返回用所需TimeZone和/或Locale默认值准备好的实例。

回答by Fedearne

I often use static factory methods instead of or in conjunction with public constructors.

我经常使用静态工厂方法代替公共构造函数或与公共构造函数结合使用。

I do this, when i need a constructor that does something you would not expect a constructor to do. I.e. load settings from a file or database.

我这样做,当我需要一个构造函数来做一些你不希望构造函数做的事情时。即从文件或数据库加载设置。

This approach also provides the possibility of naming the "constructors", based on what they do. This is especially useful, when the parameters themselves are not enough to figure out what happens in a constructor.

这种方法还提供了根据“构造函数”的作用来命名“构造函数”的可能性。当参数本身不足以弄清楚构造函数中发生了什么时,这尤其有用。

Sun uses this approach in

Sun 将这种方法用于

Class.forName("java.lang.Integer");

and

Boolean.valueOf("true");

回答by Danni

First of all, you can't dismiss static-methods there is a reason people still use it.

首先,你不能忽视静态方法,人们仍然使用它是有原因的。

  1. some design patterns are based on static methods, singleton for example:

    Config.GetInstance();

  2. Helper functions, lets say you have a byte-stream and you want a function to convert it into a string of Hex numbers.

  1. 一些设计模式基于静态方法,例如单例:

    Config.GetInstance();

  2. 辅助函数,假设您有一个字节流,并且您想要一个函数将其转换为一串十六进制数字。

there are many uses for static-methods, saying that does not mean that some people abuse it too much(Code Review is best option when people abuse code).

静态方法有很多用途,这并不意味着有些人滥用它太多(当人们滥用代码时,代码是最好的选择)。

回答by Paul

Util classes can be OK to be static. As in someone elses example above, with escaping strings. The problem lies when those utils classes perform functions that we would want to mock. For example, the FileUtils class in apache commons - it is often the case that I want to mock file interactions without having to play with real files. If this was an instance class, it would be easy.

Util 类可以是静态的。就像上面其他人的例子一样,使用转义字符串。问题在于当这些 utils 类执行我们想要模拟的功能时。例如,apache commons 中的 FileUtils 类 - 通常情况下我想模拟文件交互而不必玩真实文件。如果这是一个实例类,那就很容易了。

回答by Sridhar Sarnobat

It's much easier to refactor methods that are static. It discourages unnecessary references to field members that make the coupling tight. It's also easier to understand calling code because it explicitly passes any objects it interacts with.

重构静态方法要容易得多。它不鼓励对使耦合紧密的字段成员进行不必要的引用。调用代码也更容易理解,因为它显式地传递了与之交互的任何对象。