Java静态方法pros&缺点

时间:2012-03-02 22:26:37

标签: 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;
    }

}

这是我应该避免的吗?传递一个对象以便使用对象方法更好吗?布尔值finished现在算作全局,还是安全?

4 个答案:

答案 0 :(得分:6)

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

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

答案 1 :(得分:5)

  

这是我应该避免的吗?

总的来说,是的。静态表示全局状态。全局状态难以推理,难以单独测试,并且通常具有更高的线程安全要求。

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

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

当然,如果静态方法不需要影响任何状态 - 即如果它 - 那么它会变得更好一些。此时,您失去的是替换该方法实施的能力,例如:在测试调用它的东西时。

答案 2 :(得分: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 

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

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

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

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

答案 3 :(得分:2)

通常,通过使finished静态,您创建的情况是,任何时候只有一个MainLoop类的实例执行run。如果有多个实例,则设置finished将结束所有实例 - 而不是通常所需的内容。

但是,在这个特定的场景中,您希望结束应用程序",可能意味着您希望结束MainLoop的所有实例,方法可能是合理的。

然而,这种方法可能值得采用的情况很少,并且“#”更清洁"处理此方案的方法是保留static实例列表并完成列表,在每个实例中设置实例变量finished。这允许您也结束单个实例,为您提供现有实例的自然计数等。