Java:何时使用静态方法

Java: when to use static methods

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

例如

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

1
Obj.someMethod

(这是静态方式吗?)

我很困惑!


一条经验法则:问问你自己,"调用这个方法是否有意义,即使还没有构建obj?"如果是这样,它肯定是静态的。

所以在一个类Car中,你可能有一个方法double convertMpgToKpl(double mpg)是静态的,因为你可能想知道35mpg转换成什么,即使没有人造过车。但是void setMileage(double mpg)(它设置了一辆车的效率)不能是静态的,因为在建造任何一辆车之前调用该方法是不可能的。

(顺便说一句,反过来也不总是正确的:有时您可能有一个方法涉及两个Car对象,但仍然希望它是静态的。如Car theMoreEfficientOf( Car c1, Car c2 )。尽管可以将其转换为非静态版本,但有些人认为,由于没有"特权"选择哪辆车更重要,因此不应强制调用方选择一辆车作为将调用方法的对象。不过,这种情况只占所有静态方法的一小部分。)


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

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

  • 使用静态方法有一些合理的原因:

    • 性能:如果您希望运行一些代码,并且不希望实例化一个额外的对象来执行此操作,请将其推送到静态方法中。JVM还可以对静态方法进行很多优化(我想我曾经读过James Gosling的文章,他声明在JVM中不需要自定义指令,因为静态方法同样快,但找不到源代码——因此可能是完全错误的)。是的,这是微观优化,可能不需要。我们程序员从不因为他们很酷就做不必要的事情,对吧?

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

    • 添加方法:你真的希望类字符串有一个EDCOX1的3个实例方法,但是它不存在(并且它不应该,因为你的项目的特殊字符可能与另一个项目不同),并且你不能添加它(因为Java有点理智),所以你创建了一个实用类,并调用EDCOX1×4,而不是EDCOX1×5。甜的。

    • 纯度:采取一些预防措施,静态方法将是一个纯函数,也就是说,它唯一依赖的就是它的参数。数据输入,数据输出。这更容易阅读和调试,因为您不需要担心继承的怪癖。您也可以使用实例方法,但是编译器将在静态方法(不允许引用实例属性、重写方法等)方面为您提供更多帮助。

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

    现在,更重要的是,为什么您不想创建一个静态方法?基本上,多态性超出了窗口。您将无法重写该方法,<罢工>也不在接口< /打击>(Java 8)中声明它。你的设计需要很大的灵活性。另外,如果您需要状态,如果不小心的话,最终会出现大量并发错误和/或瓶颈。


    在阅读了misko的文章之后,我认为从测试的角度来看静态方法是不好的。您应该改为拥有工厂(可能使用像guice这样的依赖注入工具)。

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

    only have one of something
    The problem of"how do I ensure that I
    only have one of something" is nicely
    sidestepped. You instantiate only a
    single ApplicationFactory in your
    main, and as a result, you only
    instantiate a single instance of all
    of your singletons.

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

    The basic issue with static methods is
    they are procedural code. I have no
    idea how to unit-test procedural code.
    Unit-testing assumes that I can
    instantiate a piece of my application
    in isolation. During the instantiation
    I wire the dependencies with
    mocks/friendlies which replace the
    real dependencies. With procedural
    programing there is nothing to"wire"
    since there are no objects, the code
    and data are separate.


    static方法是一种方法,不需要初始化任何对象就可以调用它。您注意到在Java中使用EDOCX1×8函数时使用EDCOX1 6吗?程序从那里开始执行,没有创建对象。

    请考虑以下示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     class Languages
     {
         public static void main(String[] args)
         {
             display();
         }

         static void display()
         {
             System.out.println("Java is my favorite programming language.");
         }
      }


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


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


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

  • 静态方法属于类而不是类的对象。
  • 在不需要创建类实例的情况下调用的静态方法。
  • 静态方法可以访问静态数据成员并更改其值。
  • 静态方法只能使用类点静态名称的名称进行访问。…示例:student9.change();
  • 如果要使用类的非静态字段,则必须使用非静态方法。
  • //修改所有对象公共属性的程序(静态字段)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    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美国广播公司333中国BBIT


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

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

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


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


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


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

    Car类可能有一个名为Accelerate()的实例方法。如果汽车确实存在(已经构造),那么您只能加速汽车,因此这将是一个实例方法。

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


    静态方法不需要在对象上调用,也就是在使用它时。示例:main()是静态的,您不创建调用它的对象。


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

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


    如果

    • 不希望对实例执行操作(实用工具方法)


      As mentioned in few of above answers in this post, converting miles to kilometers, or calculating temperature from Fahrenheit to Celsius and vice-versa. With these examples using static method, it does not need to instantiate whole new object in heap memory. Consider below

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

      the former creates a new class footprint for every method invoke, Performance, Practical. Examples are Math and Apache-Commons library StringUtils class below:

      1
      2
      3
      4
      5
      Math.random()
      Math.sqrt(double)
      Math.min(int, int)
      StringUtils.isEmpty(String)
      StringUtils.isBlank(String)
    • 一个人想用做一个简单的函数。输入被明确地传递,并得到作为返回值的结果数据。继承,对象声明不会出现在图片中。简洁易读。

    注:很少有人反对静态方法的可测试性,但是静态方法也可以测试!使用jmockit,可以模拟静态方法。可测试性。下面的例子:

    1
    2
    3
    4
    5
    6
    new MockUp<ClassName>() {
        @Mock
        public int doSomething(Input input1, Input input2){
            return returnValue;
        }
    };

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

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


    静态的:Obj.someMethod

    当您希望提供对方法的类级访问时,即在不需要类实例的情况下,可以调用方法时,使用static


    I am wondering when to use static methods?

  • static方法的一个常见用途是访问static字段。
  • 但是您可以使用static方法,而不需要引用static变量。不引用EDOCX1·0变量的辅助方法可以在JavaLang.Max之类的Java类中找到。

    1
    2
    3
    public static int min(int a, int b) {
        return (a <= b) ? a : b;
    }
  • 另一个用例,我可以想到这些方法与synchronized方法相结合的方法是在多线程环境中实现类级锁。

  • 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?

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

    "Oracle文档"页提供了更多详细信息。

    不允许实例和类变量以及方法的所有组合:

  • 实例方法可以直接访问实例变量和实例方法。
  • 实例方法可以直接访问类变量和类方法。
  • 类方法可以直接访问类变量和类方法。
  • 类方法不能直接访问实例变量或实例方法,它们必须使用对象引用。此外,类方法不能使用this关键字,因为没有要引用的实例。

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

  • 对于不需要任何对象状态的实用程序或帮助器方法。因为不需要访问实例变量,所以方法消除了调用方实例化对象的需要只是调用方法。
  • 为所有人共享的国家类的实例,如计数器。所有实例都必须共享相同的状态。只使用该状态的方法应该是静态的好。

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

    eclipse setting