【问题标题】:When to use static method and field?何时使用静态方法和字段?
【发布时间】:2013-07-11 10:04:17
【问题描述】:

我知道什么是静态,但不确定何时使用它。

静态变量: 我只将它用于常量字段。有时一个类中有几十个常量,所以使用静态常量可以节省大量内存。还有其他典型用例吗?

静态方法: 我在做关于算法的课程时使用它。例如,提供不同排序算法的类。是否违反 OOP 设计?我认为最好保持这种方式,而不是在需要使用它们的每个类中实现排序算法。我错了吗?有哪些好的用例?

另外,使用静态和非静态字段/方法之间是否存在性能差异?

【问题讨论】:

  • 静态类级方法,非静态对象级方法

标签: java performance oop static


【解决方案1】:

static field 在所有对象中只有一个值,他们称它为类成员也是因为它与类有关。

  • 您可以将静态文件用作实用程序。

    一个例子假设我们需要知道我们有多少个实例:

Counter

     public class Counter {


     public static int instanceCount ;

        public Counter()
        {
            instanceCount++;
        }

        public int getInstanceCount()
        {
            return instanceCount;
        }



    }

创建Counter 类的两个实例后。但是它们共享相同的 instanceCount 字段,因为它是一个静态字段,因此 instanceCount 的值将在 firstCountersecondCounter 中变得相同。

班级main

       Counter firstCounter = new Counter();
       // will print 1
       System.out.println(co.getInstanceCount());
       // will print 2
        Counter secondCounter = new Counter();

        System.out.println(co1.getInstanceCount());

【讨论】:

    【解决方案2】:

    静态变量属于一个类,因此由所有对象共享,因此如果您确实希望共享该变量,则内存使用量会更少。如果您将变量声明为 public 和 static,那么它对所有人都是全局可用的。

    静态方法通常是实用方法,取决于访问修饰符,它们可以在类内或跨类使用。静态实用程序类将有助于再次减少内存使用量,因为您无需创建对象来调用这些方法。

    【讨论】:

    • 不同意静态变量用于全局变量。他们是两个不同的东西。私有静态变量可以是类常量,但这不会使其成为全局变量。全局变量通常违反 OOP,而静态变量则不然。
    【解决方案3】:

    除了非常特殊的情况,我只使用静态(和最终)变量作为常量。当然,使用它们是完全有效的。

    我倾向于避免使用静态实用程序方法,因为它们使为代码编写单元测试变得更加困难(模拟方法调用的结果)。当你开始开发测试驱动方式时,这个问题就变得很明显了。我更喜欢使用依赖注入和单例 bean(尽管这取决于您的需求和情况)。

    【讨论】:

    • 我认为限制某些东西编程的东西是不好的.. :d,你避免使用静态 util 方法,这样会更难编写单元测试,那么它不是静态的问题
    【解决方案4】:

    还有其他典型的用例吗?

    全局变量

    是否违反 OOP 设计?

    不准确,关键是静态方法是无状态的,因为您不需要类的特定实例。我最喜欢的方法是实用方法(如 Apache Commons)。但您可能会意识到,有些方法可能更适合作为类成员而不是静态成员。

    一旦您无法覆盖这些方法或被模拟实现替换,静态方法也会使类的可测试性变得更加困难。

    性能差异?

    Google 有一个性能 Android 建议,上面写着“更喜欢静态而不是虚拟”:

    http://developer.android.com/training/articles/perf-tips.html#PreferStatic

    我不确定 JVM 是否如此,因为 Android 使用不同的 VM,但鉴于链接指出的原因,这是有道理的:

    如果您不需要访问对象的字段,请将您的方法设为静态。调用将快 15%-20% 左右。这也是一种很好的做法,因为您可以从方法签名中看出调用该方法不能改变对象的状态。”

    【讨论】:

    • +1 表示唯一尝试回答性能问题的人,虽然我想知道 pc 上的性能差异。
    【解决方案5】:

    您正在描述您使用静态的情况,但这并不能从根本上解释为什么您会使用静态与非静态 - 它们不仅仅是常量和实用方法的关键字。

    当某些东西不是静态的(实例)时,它意味着对于该类的每个实例都有它的一个实例。每一个都可以独立改变。

    当某些东西是静态的时,这意味着该类的所有实例只有一个副本,因此从任何位置更改它都会影响所有其他位置。

    静态变量/方法通常使用较少的内存,因为它们只有一个副本,无论您拥有多少类实例。如果使用得当,静力学在面向对象设计中非常适用。

    如果您有一个只需要一个实例的方法/变量(例如常量或实用程序方法),那么只需将其设为静态即可。理解虽然将方法设为静态意味着它不能被覆盖。因此,如果您想在子类中覆盖某个方法,请不要将其设为静态。

    一般的经验法则是 - 如果您只需要一份副本,请将其设为静态。如果您需要每个实例的副本,则将其设为非静态。

    【讨论】:

    【解决方案6】:

    我个人的经验法则是静态事物“只是挂在那里”。它们是全局性的(免责声明,不完全正确),但包含在这一特定类中是有意义的。

    如果您发现自己反复加载一些重量级对象,则静态字段非常有用。例如,我现在正在处理的项目有两个图像之间的切换。这些是与应用程序一起加载并保存在内存中的静态字段,而不是每次都重新加载它们并让 GC 处理这些混乱。

    【讨论】:

    • 在这种情况下,将SoftReference 存储到图像中,如果垃圾收集器清除了引用,则重新恢复它们..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-19
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 2014-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多