Java:何时使用静态方法

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

例如

Obj x = new Obj(); x.someMethod 

要么

 Obj.someMethod 

(这是静态的方式?)

我很困惑!

一个经验法则是:问问自己“调用这个方法是否合理,即使没有构造Obj? 如果是这样,那一定是静态的。

所以在一个class级的Car你可能会有一个double convertMpgToKpl(double mpg)的方法,这个方法是静态的,因为有人可能想知道35mpg转换成什么,即使没有人build立过Car。 但是void setMileage(double mpg) (设置一个特定Car的效率)不能是静态的,因为在构造Car之前调用该方法是不可思议的。

(顺便说一下,反过来并不总是正确的:有时你可能有一个涉及两个Car对象的方法,并且仍然希望它是静态的,例如Car theMoreEfficientOf( Car c1, Car c2 ) 。虽然这可以转换为非 – 有些人会认为,既然没有“特权”select哪个车更重要,你不应该强迫一个来电者select一个车作为你要调用该方法的对象。尽pipe如此,所有静态方法的一小部分)。

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

  1. 如果您正在编写实用程序课程,并且不应该更改它们。
  2. 如果该方法没有使用任何实例variables。
  3. 如果有任何操作不依赖于实例创build。
  4. 如果有一些代码可以很容易地被所有的实例方法共享,那么将这些代码抽取成一个静态的方法。
  5. 如果您确定该方法的定义将永远不会被改变或覆盖。 由于静态方法不能被覆盖。

有一些有效的理由使用静态方法:

  • 性能 :如果你想要运行一些代码,并且不想实例化一个额外的对象来实现这个目的,那么把它转换成一个静态的方法。 JVM也可以优化静态方法(我想我曾经读过James Gosling,声明你不需要在JVM中定制指令,因为静态方法会一样快,但是找不到源代码)这可能是完全错误的)。 是的,这是微型优化,可能不需要。 而我们的程序员从来不会做不必要的事情,只是因为它们很酷,对吧?

  • 实用性 :不是调用new Util().method(arg)Util.method(arg)用静态导入调用Util.method(arg)或者method(arg) 。 更简单,更短。

  • 添加方法 :你真的希望类String有一个removeSpecialChars()实例方法,但它不存在(它不应该,因为你的项目的特殊字符可能不同于其他项目),你不能添加它(因为Java有点理智),所以你创build了一个实用程序类,并调用removeSpecialChars(s)而不是s.removeSpecialChars() 。 甜。

  • 纯度 :采取一些预防措施,你的静态方法将是一个纯函数 ,也就是说,它唯一依赖的是它的参数。 数据input,数据输出。 这是更容易阅读和debugging,因为你没有inheritance怪癖担心。 你也可以用实例方法来实现,但是编译器会通过静态方法(通过不允许引用实例属性,覆盖方法等)来帮助你。

如果你想创build一个单例,你还必须创build一个静态方法,但是不要。 我的意思是,三思。

现在,更重要的是, 为什么你不想创build一个静态方法? 基本上, 多态性不在窗口中 。 您将无法重写该方法, 也不能在接口 (在Java 8之前)中 声明它 。 从devise中需要很多的灵活性。 另外,如果你需要状态的话 ,如果你不小心的话,你会得到大量的并发错误和/或瓶颈。

在阅读Misko的文章后,我认为从testing的angular度来看, 静态方法是不好的。 你应该有工厂,而不是使用像Guice这样的dependency injection工具。

我如何确保我只有一件事

只有一件事“我怎么确保我只有一件东西”被很好的回避了。 你只在你的main中实例化一个ApplicationFactory,结果,你只能实例化所有的单例的一个实例。

静态方法的基本问题是它们是程序代码

静态方法的基本问题是它们是程序代码。 我不知道如何对程序代码进行unit testing。 unit testing假定我可以孤立地实例化一个应用程序。 在实例化过程中,我使用mocks / friendlies替代真正的依赖关系。 通过程序编程,没有任何东西可以“连线”,因为没有对象,代码和数据是分开的。

static方法是一种不需要任何对象进行初始化的方法。 你有没有注意到在Java的mainfunction使用static ? 程序执行从那里开始,没有创build对象。

考虑下面的例子:

  class Languages { public static void main(String[] args) { display(); } static void display() { System.out.println("Java is my favorite programming language."); } } 

java中的静态方法属于类(不是它的一个实例)。 它们不使用实例variables,通常会从参数中获取input,对其执行操作,然后返回一些结果。 实例方法与对象相关联,顾名思义,可以使用实例variables。

不,静态方法不与一个实例相关联; 他们属于这个class级。 静态方法是你的第二个例子。 实例方法是第一个。

静态方法不与一个实例相关联,所以它们不能访问类中的任何非静态字段。

如果该方法不使用类的任何字段(或仅使用静态字段),则可以使用静态方法。

如果使用某个类的任何非静态字段,则必须使用非静态方法。

实际上,我们在一个类中使用静态属性和方法的时候,我们想要使用我们程序的一部分应该存在,直到我们的程序运行。 我们知道,为了操作静态属性,我们需要静态方法,因为它们不是实例variables的一部分。 而没有静态方法,操纵静态属性是耗时的。

如果您使用任何方法应用static关键字,则称为静态方法。

  1. 静态方法属于类而不是类的对象。
  2. 调用一个静态方法,而不需要创build一个类的实例。
  3. 静态方法可以访问静态数据成员并可以更改它的值。

//改变所有对象(静态字段)的公共属性的程序。

 class Student9{ int rollno; String name; static String college = "ITS"; static void change(){ college = "BBDIT"; } Student9(int r, String n){ rollno = r; name = n; } void display (){System.out.println(rollno+" "+name+" "+college);} public static void main(String args[]){ Student9.change(); Student9 s1 = new Student9 (111,"Indian"); Student9 s2 = new Student9 (222,"American"); Student9 s3 = new Student9 (333,"China"); s1.display(); s2.display(); s3.display(); } } 

O / P:111印度BBDIT 222美国BBDIT 333中国BBDIT

静态方法是Java中的方法,可以在不创build类的对象的情况下调用。 它属于class级。

当我们不需要使用实例调用方法时,我们使用静态方法。

如果您希望能够在没有该类的实例的情况下访问该方法,请使用静态方法。

静态方法和variables是Java中“全局”函数和variables的控制版本。 在哪些方法可以作为classname.methodName()classInstanceName.methodName()来访问,即静态方法和variables可以使用类名称以及类的实例来访问。

类不能被声明为静态的(因为它是没有意义的,如果一个类声明为public的,它可以从任何地方访问),内部类可以被声明为静态的。

静态方法不需要在对象上调用,也就是当你使用它时。 例如:你的Main()是一个静态的,你不需要创build一个对象来调用它。

静态: Obj.someMethod

当你想提供一个方法的类级访问时,使用static ,也就是说,该方法应该可以调用,而不需要类的实例。

可以使用静态方法

  • 一个不想对一个实例执行一个操作(实用方法)

    正如在这篇文章中提到的上述答案中的几个所述,将公里转换为公里,或者从华氏温度计算到摄氏温度,反之亦然。 通过这些使用静态方法的示例,它不需要在堆内存中实例化整个新对象。 考虑下面

     1. new ABCClass(double farenheit).convertFarenheitToCelcium() 2. ABCClass.convertFarenheitToCelcium(double farenheit) 

    前者为每个方法调用, 性能,实用创build一个新的类占用空间。 例如Math和Apache-Commons库StringUtils类如下:

     Math.random() Math.sqrt(double) Math.min(int, int) StringUtils.isEmpty(String) StringUtils.isBlank(String) 
  • 一个想用作简单的function。 input显式传递,并将结果数据作为返回值。 inheritance,对象实例化不进入图片。 简洁,易读

:很less有人反对静态方法的可testing性,但静态方法也可以testing! 用jMockit,可以模拟静态方法。 可测性 。 示例如下:

 new MockUp<ClassName>() { @Mock public int doSomething(Input input1, Input input2){ return returnValue; } }; 

我想知道什么时候使用静态方法?

  1. static方法的一个常见用途是访问static字段。
  2. 但是你可以有static方法,而不需要引用staticvariables。 没有引用staticvariables的Helper方法可以在java.lang.Math等java类中find

     public static int min(int a, int b) { return (a <= b) ? a : b; } 
  3. 另一个用例,我可以想象这些方法结合synchronized方法是在multithreading环境下实现类级locking。

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

如果你需要访问类的实例对象的方法,你的方法应该是非静态的。

Oracle文档页面提供了更多的细节。

不是所有的实例和类variables和方法的组合都是允许的:

  1. 实例方法可以直接访问实例variables和实例方法。
  2. 实例方法可以直接访问类variables和类方法。
  3. 类方法可以直接访问类variables和类方法。
  4. 类方法不能直接访问实例variables或实例方法 – 它们必须使用对象引用。 此外,类方法不能使用this关键字,因为没有这个实例可以引用。

在eclipse中,你可以启用一个警告来帮助你检测潜在的静态方法。 (突出显示的行上面是另一个我忘记突出显示的行)

日食设置

静态方法在类的所有实例之间共享,开发人员通常使用静态关键字和实用程序方法,这些方法执行应用程序中任何地方经常使用的常用function。

如果以下条件适用,则使您的方法是静态的:

  1. 你的方法做了一个在整个应用程序中经常使用的通用function。
  2. 你的方法不使用实例variables。
  3. 你的方法接受input作为参数,做一些共同的function,然后返回一些结果。

PS:值得一提的是,模拟一个静态方法是非常困难的,甚至是(不可能的),嘲笑是一个用于unit testing的机制来伪造一些方法的业务。

有关更多详细信息,请检查: java中的static关键字