我想知道何时使用静态方法?假设我有一个带有几个getter和setter的类,一个或两个方法,我希望这些方法只能在类的实例对象上调用。这是否意味着我应该使用静态方法?
e.g
Obj x = new Obj();
x.someMethod
或
Obj.someMethod
(这是静态方式吗?)
我很困惑!
答案 0 :(得分:1336)
一个经验法则:问问自己“即使没有构建Obj,这个方法也有意义吗?”如果是这样,那肯定是静态的。
因此,在类Car
中,您可能有一个静态的方法double convertMpgToKpl(double mpg)
,因为有人可能想知道35mpg转换为什么,即使没有人构建过汽车。但是void setMileage(double mpg)
(设置一个特定Car的效率)不能是静态的,因为在构造任何Car之前调用该方法是不可思议的。
(顺便说一下,反过来并不总是这样:你有时会有一个涉及两个Car
个对象的方法,但仍然希望它是静态的。例如Car theMoreEfficientOf( Car c1, Car c2 )
。虽然这可以被转换对于非静态版本,有人会争辩说,由于没有“特权”选择哪个Car更重要,所以不应强制调用者选择一个Car作为您将调用该方法的对象。但是,这种情况只占所有静态方法的一小部分。)
答案 1 :(得分:495)
仅在以下方案中定义静态方法:
答案 2 :(得分:159)
使用静态方法有一些正当理由:
性能:如果您希望运行某些代码,并且不想实例化额外的对象,请将其推送到静态方法中。 JVM也可以大量优化静态方法(我想我曾经读过James Gosling声明你不需要JVM中的自定义指令,因为静态方法会同样快,但找不到源 - 因此它可能是完全错误的)。是的,它是微优化,可能不需要。我们程序员从不做不需要的事情只是因为它们很酷,对吗?
实用性:不要拨打new Util().method(arg)
,而是使用静态导入调用Util.method(arg)
或method(arg)
。更简单,更短。
添加方法:你真的希望类String有一个removeSpecialChars()
实例方法,但它不存在(它不应该,因为你的项目的特殊字符可能与其他项目不同),你不能添加它(因为Java有点理智),所以你创建了一个实用程序类,并调用removeSpecialChars(s)
而不是s.removeSpecialChars()
。甜。
纯度:采取一些预防措施,您的静态方法将是pure function,也就是说,它唯一依赖的是它的参数。数据输入,数据输出。这更容易阅读和调试,因为您没有担心继承怪癖。您也可以使用实例方法来完成它,但编译器将使用静态方法帮助您(通过不允许引用实例属性,重写方法等)。
如果你想制作单身,你还必须创建一个静态方法,但是......不要。我的意思是,三思而后行。
现在,更重要的是,为什么你不希望创建静态方法?基本上,多态性不在窗口。您将无法覆盖方法,也无法在接口 (Java 8之前版本)中声明它。它从您的设计中获得了很大的灵活性。此外,如果您需要状态,如果您不小心,最终会出现大量并发错误和/或瓶颈。
答案 3 :(得分:39)
在阅读Misko的文章后,我认为static methods从测试的角度来看是不好的。您应该使用factories(可能使用依赖注入工具,如Guice)。
只有一个东西 “如何确保我的问题” 只有一个“很好的东西 回避。您只实例化一个 您的单个ApplicationFactory 主要的,因此,你只 实例化所有的单个实例 你的单身人士。
静态方法的基本问题是 它们是程序代码。我没有 想法如何对程序代码进行单元测试。 单元测试假设我可以 实例化我的一个应用程序 处于隔离状态。在实例化期间 我用依赖关系连接 嘲笑/友谊取代了 真正的依赖。随着程序 编程没有“连线” 因为没有对象,代码 和数据是分开的。
答案 4 :(得分:31)
static
方法是一种方法,它不需要初始化任何对象来调用它。您是否注意到Java中的static
函数中使用了main
?程序执行从那里开始,没有创建对象。
考虑以下示例:
class Languages
{
public static void main(String[] args)
{
display();
}
static void display()
{
System.out.println("Java is my favorite programming language.");
}
}
答案 5 :(得分:18)
java中的静态方法属于该类(不是它的实例)。它们不使用实例变量,通常从参数中获取输入,对其执行操作,然后返回一些结果。 Instances方法与对象相关联,顾名思义,它可以使用实例变量。
答案 6 :(得分:11)
不,静态方法与实例无关;他们属于这个班级。静态方法是你的第二个例子;实例方法是第一个。
答案 7 :(得分:11)
如果使用任何方法应用static关键字,则称为静态方法。
//更改所有对象的公共属性的程序(静态字段)。
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 :(得分:8)
静态方法与实例无关,因此无法访问类中的任何非静态字段。
如果方法不使用类的任何字段(或仅静态字段),则可以使用静态方法。
如果使用类的任何非静态字段,则必须使用非静态方法。
答案 9 :(得分:6)
实际上,我们在类中使用静态属性和方法,当我们想要使用我们程序的某些部分应该存在时,直到我们的程序运行。我们知道,要操纵静态属性,我们需要静态方法,因为它们不是实例变量的一部分。如果没有静态方法,操作静态属性非常耗时。
答案 10 :(得分:6)
应该在Class上调用静态方法,应该在Class的Instances上调用Instance方法。但这在现实中意味着什么呢?这是一个有用的例子:
汽车类可能有一个名为Accelerate()的实例方法。如果汽车实际存在(已经构建),你只能加速汽车,因此这将是一个实例方法。
汽车类也可能有一个名为GetCarCount()的计数方法。这将返回创建(或构建)的汽车总数。如果没有构建汽车,这个方法将返回0,但它仍然可以被调用,因此它必须是静态方法。
答案 11 :(得分:5)
如果希望能够在没有类实例的情况下访问该方法,请使用静态方法。
答案 12 :(得分:4)
不需要在对象上调用静态方法,也就是在使用它时。示例:您的Main()是静态的,您不会创建一个对象来调用它。
答案 13 :(得分:4)
静态方法和变量是Java中“全局”函数和变量的受控版本。可以使用classname.methodName()
或classInstanceName.methodName()
访问哪些方法,即可以使用类名以及类的实例访问静态方法和变量。
Class不能声明为static(因为它没有意义。如果一个类被声明为public,它可以从任何地方访问),内部类可以声明为static。
答案 14 :(得分:3)
静态:
Obj.someMethod
如果要为方法提供类级别访问权限,请使用static
,即在没有类实例的情况下应该可以调用该方法。
答案 15 :(得分:3)
如果
,可以使用静态方法您不希望对实例执行操作(实用程序方法)
正如本文上面的几个答案所提到的,将里程转换为公里,或计算从华氏温度到摄氏温度的温度,反之亦然。使用静态方法的这些示例,它不需要在堆内存中实例化整个新对象。请考虑以下
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)
想要用作简单的功能。显式传递输入,并将结果数据作为返回值。继承,对象实例不会出现。 简洁,易读 。
注意强>: 很少有人反对静态方法的可测试性,但也可以测试静态方法!使用jMockit,可以模拟静态方法。的 可测 即可。示例如下:
new MockUp<ClassName>() {
@Mock
public int doSomething(Input input1, Input input2){
return returnValue;
}
};
答案 16 :(得分:3)
静态方法是Java中可以在不创建类对象的情况下调用的方法。它属于班级。
当我们不需要使用实例调用方法时,我们使用静态方法。
答案 17 :(得分:2)
我想知道何时使用静态方法?
static
方法的一个常见用途是访问static
字段。 但您可以使用static
方法,而无需引用static
个变量。没有引用static
变量的Helper方法可以在某些java类中找到,例如java.lang.Math
public static int min(int a, int b) {
return (a <= b) ? a : b;
}
另一个用例,我可以想到这些方法结合synchronized
方法是在多线程环境中实现类级别锁定。
假设我有一个带有一些getter和setter的类,一个或两个方法,我希望这些方法只能在类的实例对象上调用。这是否意味着我应该使用静态方法?
如果需要访问类的实例对象的方法,那么您的方法应该是非静态的。
Oracle文档page提供了更多详细信息。
并非所有实例和类变量和方法的组合都是允许的:
答案 18 :(得分:2)
静态方法有两个主要目的:
答案 19 :(得分:1)
答案 20 :(得分:1)
我找到了一个很好的描述,什么时候使用静态方法:
没有硬性规定,写得很好的规则来决定何时使方法静态,但很少有基于经验的观察,这不仅有助于使方法静态化,而且还教导何时使用静态Java中的方法。您应该考虑在 Java 中使用静态方法:
如果一个方法没有修改对象的状态,或者没有使用任何实例变量。
您想在不创建该类的实例的情况下调用方法。
一个方法是静态的很好的候选者,如果它只适用于提供给它的参数,例如public int factorial(int number){},这个方法只对作为参数提供的数字进行操作。
实用方法也是静态的良好候选者,例如StringUtils.isEmpty(String text),这是一个检查字符串是否为空的实用方法。
如果方法的函数在类层次结构中保持静态,例如equals() 方法不是静态化的好选择,因为每个类都可以重新定义相等性。
来源是 here
答案 21 :(得分:0)
什么时候可以使用静态方法好?
只有两种情况下使用静态方法或变量,这不是可憎的。
静态方法不好吗?
考虑静态方法的一种方法是全局过程。 本质上,可以在任何地方任何地方调用静态方法。 它只是假装是班级的一部分,而实际上 仅用作“标签”,通过某种逻辑将方法组织起来 师。我用这些术语看待静态方法,因为创建 全局过程与面向对象设计完全相反。
静态方法的另一个主要问题是可测试性。 在构建软件时,可测试性很重要。静态方法 非常难以测试,尤其是当它们创建新的 具体类的实例。如果您曾经从事过传统工作 代码并尝试为静态方法编写单元测试,您知道我的 痛苦。
静态方法也不是多态的。如果您创建静态 类上的方法,没有覆盖该行为。你是 卡住了对该实现的硬编码引用。
最后一句话
因此,请记住当您创建静态方法进行思考时 小心。我不是在提倡永远不要使用它们。我提倡 有一个很好的理由,首先检查一下静态 方法确实属于另一个可以使用状态的类 信息。
答案 22 :(得分:0)
每当不想在代码中创建对象来调用方法时,只需将该方法声明为静态方法即可。由于静态方法不需要调用实例,但是这里要注意的是并不是所有静态方法都可以由JVM自动调用。此特权仅由Java中的main()“ public static void main [String ... args]”方法享有,因为在运行时,这是JVM寻求Signature public“ static” void main []作为入口的方法。开始执行代码。
示例:
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 itself
Demo.Displ(); //By using class name//Recommended
d.Displ(); //By using instance //Not recommended
}
public static void Displ()
{
System.out.println("This static method needs to be called explicitly");
}
}
输出:- 该静态方法由JVM执行 该静态方法需要显式调用 该静态方法需要显式调用 该静态方法需要显式调用