何时使用静态方法

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

示例:

Obj x = new Obj();x.someMethod();

…或:

Obj.someMethod(); // Is this the static way?

我很困惑!

1261140 次浏览

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

不,静态方法不与实例关联;它们属于类。静态方法是您的第二个示例;实例方法是第一个。

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

静态:Obj.someMethod

当您想提供对方法的类级访问时,请使用static,即该方法应该可以在没有类实例的情况下调用。

静态方法不与实例关联,因此它们不能访问类中的任何非静态字段。

如果方法不使用类的任何字段(或仅使用静态字段),您将使用静态方法。

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

一个经验法则:问问自己“即使还没有构造对象,调用这个方法是否有意义?”如果是这样,它肯定应该是静态的。

所以在类Car中,你可能有一个方法:

double convertMpgToKpl(double mpg)

…这将是静态的,因为人们可能想知道35mpg转换为什么,即使没有人构建过Car。但是这个方法(设置一个特定Car的效率):

void setMileage(double mpg)

…不能是静态的,因为在构造任何Car之前调用方法是不可想象的。

(顺便说一句,反过来并不总是正确的:有时你可能有一个涉及两个Car对象的方法,但仍然希望它是静态的。例如:

Car theMoreEfficientOf(Car c1, Car c2)

尽管这可以转换为非静态版本,但有些人会争辩说,由于没有“特权”选择哪个Car更重要,因此您不应该强制调用者选择一个Car作为您将调用该方法的对象。不过,这种情况只占所有静态方法的一小部分。

在阅读了Misko的文章之后,我认为从测试的角度来看静态方法是不好的。你应该用工厂代替(也许使用像Guice这样的依赖注入工具)。

我如何确保我只有一个东西

只有一个东西“我如何确保我“只有一个东西”很好回避。你只实例化一个单一应用工厂在您主要的,结果,你只实例化所有的单个实例《你的单身》

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

静态方法的基本问题是它们是程序代码。我没有了解如何对过程代码进行单元测试。单元测试假设我可以实例化我的应用程序的一部分孤立地。在实例化期间我将依赖关系与模拟/友谊赛取代了真正的依赖。与程序编程没有什么可以“连接”的由于没有对象,代码数据是分开的

静态方法不需要在对象上调用,那就是你使用它的时候。示例:您的Main()是静态的,您没有创建一个对象来调用它。

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

  1. 如果您正在编写实用程序类,并且它们不应该被更改。
  2. 如果该方法未使用任何实例变量。
  3. 如果任何操作不依赖于实例创建。
  4. 如果有一些代码可以很容易地被所有实例方法共享,请将该代码提取到静态方法中。
  5. 如果您确定方法的定义永远不会被更改或覆盖。因为静态方法不能被覆盖。

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

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

实际上,我们在一个类中使用静态属性和方法,当我们想使用我们程序的某些部分时,应该存在那里直到我们的程序运行。我们知道,要操作静态属性,我们需要静态方法,因为它们不是实例变量的一部分。如果没有静态方法,操作静态属性是很耗时的。

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

  • 性能优化:如果你想运行一些代码,并且不想实例化一个额外的对象,那就把它推进到静态方法中,JVM也可以非常优化静态方法(我记得我曾经读过James Gosling说在JVM中不需要自定义指令,因为静态方法也会一样快,但是找不到源代码——所以这可能完全是错误的)。是的,这是微优化,可能是不需要的。而我们程序员永远不会做不需要的事情,因为它们很酷,对吧?

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

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

  • 纯度:采取一些预防措施,你的静态方法将是一个纯函数,也就是说,它唯一依赖的是它的参数。数据输入,数据输出。这更容易阅读和调试,因为你不必担心继承怪癖。你也可以用实例方法做到这一点,但编译器会在静态方法上帮助你更多(通过不允许引用实例属性、覆盖方法等)。

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

现在,更重要的是,为什么你不想来创建一个静态方法?基本上,多态性从窗口消失了。你将无法覆盖该方法,也不在接口中声明它(Java8)。它需要你的设计有很大的灵活性。此外,如果你需要,如果你不小心,你最终会遇到很多并发错误和/或瓶颈。

static方法是一种不需要初始化任何对象就可以调用的方法。你注意到Java的main函数中使用了static吗?程序执行从那里开始,没有创建对象。

考虑以下示例:

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

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

  1. 静态方法属于类而不是类的对象。
  2. 无需创建类实例即可调用的静态方法。
  3. 静态方法可以访问静态数据成员并可以更改其值。
  4. 静态方法可以只使用类点静态名称 . . . 例子:Student9.change();
  5. 如果要使用类的非静态字段,则必须使用非静态方法。

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

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印度BBDIT222美国BBDIT333中国BBDIT

可以使用静态方法,如果

  • 不想对实例执行操作(实用程序方法)

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

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

    前者为每个方法调用创建一个新的类占用,性能,实用。下面的示例是Math和Apache-Commons库StringUtils类:

    Math.random()Math.sqrt(double)Math.min(int, int)StringUtils.isEmpty(String)StringUtils.isBlank(String)
  • One wants to use as a simple function. Inputs are explictly passed, and getting the result data as return value. Inheritence, object instanciation does not come into picture. Concise, Readable.

NOTE:Few folks argue against testability of static methods, but static methods can be tested too! With jMockit, one can mock static methods. Testability. Example below:

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

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

eclipse设置

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

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

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

  1. static方法的一个常见用途是访问static字段。
  2. 但是你可以有static方法,而不引用static变量。在一些java类中可以找到不引用static变量的辅助方法,例如java.lang.数学

    public static int min(int a, int b) {return (a <= b) ? a : b;}
  3. The other use case, I can think of these methods combined with synchronized method is implementation of class level locking in multi threaded environment.

Say if I have a class with a few getters and setters, a method or two, and I want those methods only to be invokable on an instance object of the class. Does this mean I should use a static method?

If you need to access method on an instance object of the class, your method should should be non static.

Oracle documentation page provides more details.

Not all combinations of instance and class variables and methods are allowed:

  1. Instance methods can access instance variables and instance methods directly.
  2. Instance methods can access class variables and class methods directly.
  3. Class methods can access class variables and class methods directly.
  4. Class methods cannot access instance variables or instance methods directly—they must use an object reference. Also, class methods cannot use the this keyword as there is no instance for this to refer to.

静态方法有两个主要目的:

  1. 对于不需要任何对象状态的实用程序或辅助方法。由于不需要访问实例变量,因此具有静态方法消除了调用者实例化对象的需要只是为了调用该方法。
  2. 对于所有人共享的状态类的实例,例如计数器。所有实例都必须共享相同的状态。仅使用该状态的方法应该是静态的嗯。

静态方法应该在Class上调用,实例方法应该在Class的实例上调用。但这在现实中意味着什么?这是一个有用的例子:

一个car类可能有一个名为Accelerate()的实例方法。您只能加速一辆汽车,如果汽车实际存在(已构建),因此这将是一个实例方法。

汽车类也可能有一个名为GetCarCount()的计数方法。这将返回创建(或构造)的汽车总数。如果没有构造汽车,此方法将返回0,但它应该仍然能够被调用,因此它必须是一个静态方法。

每当你不想创建一个对象来调用代码中的方法时,只需声明该方法为静态。由于静态方法不需要调用实例,但这里的catch并不是所有的静态方法都由JVM自动调用。这种特权只有java中的main()"public静态valmain main[String… args]"方法才能享受,因为在运行时,这是JVM寻求的Signature public"静态"valmain[]方法,作为开始执行代码的切入点。

示例:

public class Demo{public static void main(String... args){Demo d = new Demo();
System.out.println("This static method is executed by JVM");
//Now to call the static method Displ() you can use the below methods:Displ(); //By method name itselfDemo.Displ(); //By using class name//Recommendedd.Displ(); //By using instance //Not recommended}
public static void Displ(){System.out.println("This static method needs to be called explicitly");}}

输出:-这个静态方法由JVM执行这个静态方法需要显式调用这个静态方法需要显式调用这个静态方法需要显式调用

我找到了一个很好的描述,何时使用静态方法:

没有硬性的、写得很好的规则来决定何时使方法静态化,但很少有基于经验的观察,这不仅有助于使方法静态化,还教会了Java何时使用静态方法。你应该考虑在Java中使方法静态化:

  1. 如果一个方法不修改对象的状态,或者不使用任何实例变量。

  2. 您想在不创建该类实例的情况下调用方法。

  3. 一个方法是静态的好候选者,如果它只对提供给它的参数起作用,例如public int factorial(int num){},这个方法只对作为参数提供的数字起作用。

  4. 实用方法也是静态的很好的候选者,例如StringUtils.is空(字符串文本),这是一个实用方法来检查字符串是否为空。

  5. 如果方法的函数在类层次结构中保持静态,例如equals()方法不是一个很好的静态候选者,因为每个类都可以重新定义相等。

来源这里

您应该在任何时候使用静态方法,

  1. 方法中的代码不依赖于实例创建,并且是不使用任何实例变量。
  2. 一段特定的代码将由所有实例方法共享。
  3. 方法的定义不应更改或覆盖。
  4. 您正在编写不应更改的实用程序类。

https://www.tutorialspoint.com/When-to-use-static-methods-in-Java