Java静态方法的优点和缺点

Luc*_*elt 8 java static

我之前没有使用过很多静态方法,但最近我倾向于使用更多静态方法.例如,如果我想在类中设置一个布尔标志,或者在一个类中设置一个布尔标志而不需要通过类传递实际对象.

例如:

public class MainLoop
{
    private static volatile boolean finished = false;

    public void run()
    {
        while ( !finished )
        {
            // Do stuff
        }

    }
    // Can be used to shut the application down from other classes, without having the actual object
    public static void endApplication()
    {
        MainLoop.finished = true;
    }

}
Run Code Online (Sandbox Code Playgroud)

这是我应该避免的吗?传递一个对象以便使用对象方法更好吗?布尔值finished现在是否计为全局,或者它是否同样安全?

JB *_*zet 6

是的,传递物体更好.使用单例或静态方法使OO编程看起来像过程编程.单例有点好,因为你至少可以使它实现接口或扩展抽象类,但它通常是一种设计气味.

将实例方法与静态变量混合就像你正在做的那样更令人困惑:你可以让几个对象循环,但你会立刻停止它们,因为它们都会在静态变量发生变化时停止.


Jon*_*eet 5

这是我应该避免的吗?

一般来说,是的.静力学代表全球状态.全局状态难以推理,难以单独测试,并且通常具有更高的线程安全性要求.

如果我想测试某个状态下对象会发生什么,我可以创建该对象,将其置于该状态,执行我的测试,并让它被垃圾收集.

如果我想测试全局状态会发生什么,我需要确保在测试结束时(或者可能在每次测试开始时)重置所有状态.如果我不小心这样做,测试现在会相互干扰.

当然,如果静态方法不需要影响任何状态 - 即如果它是纯粹的 - 那么它会变得更好一些.那时你所失去的就是能够替换那个方法实现,例如在测试调用它的东西时.


Mik*_*ark 5

在这种情况下使用静态变量的一个问题是,如果您创建两个(或更多)MainLoop实例,编写看起来像它的代码只关闭其中一个实例,实际上将关闭它们:

MainLoop mainLoop1 = new MainLoop();
MainLoop mainLoop2 = new MainLoop();

new Thread(mainLoop1).start();
new Thread(mainLoop2).start();

mainLoop1.finished = true; // static variable also shuts down mainLoop2 
Run Code Online (Sandbox Code Playgroud)

这只是选择不使用静态变量的原因之一(在众多中).即使您的程序今天只创建了一个MainLoop,但未来您可能有理由创建其中许多:用于单元测试,或实现一个很酷的新功能.

您可能会想"如果发生这种情况,我只会重构程序以使用成员变量而不是静态变量." 但是,预先支付成本通常更有效,并且从一开始就将模块化设计融入到程序中.

毫无疑问,静态通常会使快速而肮脏的程序更容易编写.但是对于您打算在未来几年内测试,维护,增长,共享和使用的重要/复杂代码,通常建议使用静态变量.

正如对这个问题的其他答案所指出的,静态变量是一种全局变量.关于为什么(通常)全局 变量 坏的,有很多信息.