Java的:当用静态方法

问题描述 投票:822回答:20

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

e.g

Obj x = new Obj();
x.someMethod

要么

Obj.someMethod

(这是静态的方式?)

我搞糊涂了!

java static-methods
20个回答
1374
投票

一个规则的拇指:问自己“是否有意义调用此方法,即使没有的OBJ已建造了吗?”如果是的话,它绝对应该是静态的。

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

(顺便说一句,反之并不总是正确的:你可能有时是涉及两种Car对象的方法,并仍然希望它是静态的,例如Car theMoreEfficientOf( Car c1, Car c2 )虽然这可能被转换成非静态的版本,有人会说,因为没有“特权”的选择,其中轿车更重要的是,你不应该强迫呼叫者选择一个汽车为对象,你会调用该方法上,这种情况占所有静态的相当小部分方法,虽然)。


7
投票

静态方法应在类调用,实例方法应在该类的实例调用。但到底是什么,在现实中是什么意思?这里是一个有用的例子:

一辆汽车类可能有所谓的加速实例方法()。你只能加速一辆车,如果车确实存在(已建成),因此这将是一个实例方法。

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


6
投票

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


5
投票

当你想能够在无类的实例访问该方法使用一个静态方法。


4
投票

静态方法不需要在对象上被调用,那就是当你使用它。例如:你的主()是一个静态的,你不创建一个对象来调用它。


4
投票

静态方法和变量在Java中控制“全球”函数和变量的版本。其中方法可以为静态的方法和变量可以用类名以及该类的实例来访问classname.methodName()classInstanceName.methodName(),即进行访问。

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


3
投票

静态:Obj.someMethod

当你想提供一种方法,即其中的方法应该是可调用无类的实例类级别的访问使用static


3
投票

静态方法的话可以使用

  • 人们不希望在一个实例执行操作(实用方法) 正如在少数在这篇文章上述答案,转换英里公里,或计算从华氏温度为摄氏温度,反之亦然的提及。使用静态方法这些例子中,它并不需要实例全新的对象在堆内存。考虑下面 1. new ABCClass(double farenheit).convertFarenheitToCelcium() 2. ABCClass.convertFarenheitToCelcium(double farenheit) 前者会为每一个方法调用,性能,实用的一类新的足迹。例子是数学及以下Apache的共享库StringUtils类: Math.random() Math.sqrt(double) Math.min(int, int) StringUtils.isEmpty(String) StringUtils.isBlank(String)
  • 一个人想作为一个简单的功能使用。输入被显式传递,并得到结果数据作为返回值。继承,对象实例化不进入画面。简洁,可读。

注:很少人反对的静态方法可测试性,但静态方法也可以进行测试!随着jMockit,一个可以模拟静态方法。可测性。实施例下面:

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

3
投票

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

我们使用时,我们无需用实例来调用的方法静态方法。


2
投票

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

  1. 对于static方法的一个常见用途是访问static领域。
  2. 但你可以有static方法,而不引用static变量。没有涉及static可变辅助方法可以在一些Java类像java.lang.Math找到 public static int min(int a, int b) { return (a <= b) ? a : b; }
  3. 其他用途的情况下,我能想到的这些方法synchronized相结合的方法是在多线程环境中实现一流水平锁定。

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

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

Oracle文档page提供更多的细节。

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

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

2
投票

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

  1. 对于不要求任何状态实用程序或辅助方法。由于没有必要访问实例变量,其静态方法省去了呼叫者实例化对象只是调用该方法。
  2. 对于由类的所有实例共享,就像一个计数器的状态。所有实例都必须共享相同的状态。 ,仅仅使用状态的方法应该是静态的为好。

513
投票

定义仅在下列情况下,静态方法:

  1. 如果你正在写的实用工具类,他们不应该被改变。
  2. 如果这个方法不使用任何实例变量。
  3. 如果任何操作不依赖于实例的创建。
  4. 如果有一些代码,可以很容易地通过所有的实例方法被共享,提取代码到一个静态方法。
  5. 如果您确信该方法的定义将永远不会改变或撤销。由于静态方法不能被重写。

1
投票

在Eclipse中,您可以启用警告它可以帮助您检测潜在的静态方法。 (高于亮的行是另一个我忘了强调)

eclipse setting


0
投票

当静态方法能好?

只有两种情况,当正在使用静态方法或变量,它不是一个可憎的。

  1. 声明一个真正的全球常量,而不是一个全局变量。一个全局常量。例如:Math.PI.这是真的说有是宇宙的一个实例,以及宇宙单包含一个数学概念单,其中有一个特性P1不会改变一个公平的简写。因为我们习惯了在面向对象的责任的情况下不考虑PI这个概念似乎感到奇怪。如果我们设计了一些奇怪的游戏,那里有不同的数学概念和常量其它宇宙会变得更加明显。
  2. 创建对象。静态方法是创建对象的有价值的和有效的方法。称取不同的参数重载的构造函数也不是很清楚,并且经常用静态构造函数替换它们更加明确。

当静态方法是坏?

  1. 考虑静态方法的一种方式是作为全局过程。本质上是一个静态方法可以从任何地方任何调用。它只是伪装成一个类,当真正的类仅作为一个“标签”,该组织由一些逻辑上的划分方法的一部分。我看这些条款的静态方法,因为创建全局过程是面向对象设计的完全相反。
  2. 静态方法的另一个主要问题是可测性。可测性是一个大问题,构建软件的时候。静态方法是非常困难的测试,尤其是当他们创建具体类的新实例。如果你曾经在旧代码工作,并试图写单元测试的静态方法,你知道我的痛苦。
  3. 静态方法也并不多态。如果你在一个类中创建一个静态方法,也没有覆盖该行为。你坚持用硬编码引用该实现。

最后的话

所以,只记得,当您创建仔细想想一个静态方法。我不主张从来没有使用它们。我主张有一个很好的理由,并首先检查,看看是否静态方法真正属于另一个类的地方可以使用的状态信息。


166
投票

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

  • 性能:如果你想运行一些代码,并且不希望实例化一个额外的对象这样做,它推到一个静态方法。 JVM还可以优化静态方法很多(我想我曾经读过詹姆斯·高斯林,声明你不需要在JVM定制指令,因为静态方法将是一样快,但无法找到源 - 从而它可能是完全错误的)。是的,这是微优化,而且可能不需要。而我们的程序员不会做不必要的事情,只是因为它们很酷吧?
  • 实用性:而不是调用new Util().method(arg),叫Util.method(arg),或静态导入method(arg)。更简单,更短。
  • 添加方法:你真的想要String类有removeSpecialChars()实例方法,但它不存在(它不应该,因为你的项目的特殊字符可能会与其他项目的不同),而且不能添加它(因为Java是有点理智的),所以你创建一个实用工具类,而是调用removeSpecialChars(s)s.removeSpecialChars()。甜。
  • 纯度:采取一些预防措施,你的静态方法将是一个pure function,那就是它依赖于唯一的一点是它的参数。中的数据,数据出。这是更容易阅读和调试,因为你没有继承怪癖担心。你可以用实例的方法做到这一点,但是编译器会帮助你更与静态方法一点(不容许以实例引用属性,覆盖方法等)。

您还可以创建一个静态方法,如果你想一个单身,但不觉得!我的意思是,三思而后行。

现在,更重要的是,为什么你不希望创建一个静态方法?基本上,多态性就走出了窗外的。你将无法覆盖的方法, 也不在接口声明它 (预爪哇8)。这需要很多的灵活性,从你的设计。另外,如果你需要的状态,你就会有大量的并发错误和/或瓶颈,如果你不小心而告终。


40
投票

阅读MISKO的文章后,我相信static methods是坏的从一个测试点。你应该有factories代替(也许使用依赖注入的工具,像Guice)。

我怎么保证我只有东西一个

只有对某件事有一个“我怎么保证我只有东西一”是很好的回避了这个问题。你在你的主实例只有一个ApplicationFactory,并作为一个结果,你只能实例化所有单身的单个实例。

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

静态方法的基本问题是他们的程序代码。我不知道如何进行单元测试程序代码。单元测试假设我可以实例我的一块孤立的应用。在实例我丝嘲笑/友谊赛其取代真正的依赖关系的依赖关系。与过程式编程没有什么“线”,因为没有对象,代码和数据是分开的。


32
投票

static方法是要被初始化一个类型的方法,其不需要任何对象为它被调用。你注意到static在Java中的main功能中使用?程序执行从这里开始,不被创建的对象。

请看下面的例子:

 class Languages 
 {
     public static void main(String[] args) 
     {
         display();
     }

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

18
投票

在Java静态方法属于类(不是它的实例)。他们不使用实例变量,并通常会从参数上接受输入,就可以进行操作,然后返回了一些成绩。实例的方法与对象相关联,并且,顾名思义,可以使用实例变量。


11
投票

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


11
投票

如果应用static关键字用任何方法,它被称为静态方法。

  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印度BBDIT 222美国BBDIT 333中国BBDIT


8
投票

静态方法不与实例相关联,所以他们不能在课堂上访问任何非静态字段。

你可以使用一个静态方法,如果方法不使用任何类的字段(或只是静态字段)。

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

© www.soinside.com 2019 - 2024. All rights reserved.