【问题标题】:Static variable in JavaJava中的静态变量
【发布时间】:2012-09-12 10:23:46
【问题描述】:

根据 Java,静态变量可以通过类名访问,但它们也可以通过类对象访问,即使 Java 不建议这样做,并且给出了相同的答案。

我知道变量只有一个副本,并且它的值对于所有对象和其他事物都是相同的。为什么Java建议使用类名而不是类对象?

【问题讨论】:

  • 它使代码更加自文档化。它是类的变量,而不是实例的变量。
  • @BalusC 因此,如果我使用对象而不是类名,那么编写程序的方式会不会是错误的。除了使代码自我记录之外,还有任何性能原因。
  • 我认为你有正确的直觉想要学习 Java 程序员使用的典型范例,但我认为没有任何理由担心这种微优化的性能等级。无论如何,不​​,不应该对性能造成影响。
  • @BalusC 我之前已经阅读过这方面的文档,但是你的简单解释终于让我的头脑清醒了!谢谢你,非常有用!

标签: java static


【解决方案1】:

因为它可能会令人困惑!静态成员没有动态调度。

看看这个令人困惑的代码:(可能是语法错误;我的 Java 生锈了)

public abstract class Singer {
    public static void sing() {
        System.out.println("Singing");
    }
}

public class Soprano extends Singer {
    public static void sing() {
        System.out.println("Singing in the range of C4-A5");
    }
}

public class MyDriver {

    public static void main(String[] argv) {
        Singer  mySoprano1 = new Soprano();
        Soprano mySoprano2 = new Soprano();
        mySoprano1.sing();
        mySoprano2.sing();
    }

}

看着MyDriver 令人困惑,因为看起来sing 方法是多态的,所以输出应该是......

Singing in the range of C4-A5
Singing in the range of C4-A5

...因为soprano1soprano2 都是Soprano 的实例,而不是Singer

但是很可惜,输出实际上是:

Singing
Singing in the range of C4-A5

为什么?因为静态成员上没有动态分派,所以mySoprano1declared类型决定了调用哪个sing方法……而soprano1的声明类型是Singer,不是Soprano.

有关更多信息,请查看 Java Puzzlers 一书中的谜题 48“我得到的都是静态的”。

【讨论】:

  • @Makoto,我认为答案的重点是指出将调用 sing 方法是不明确的,因为 s1 被称为 Singer 而 s2 被称为Soprano 尽管两者都是 Soprano 的实例。
  • 它本身并不模棱两可——编译器最终知道——但对于开发人员来说,它具有误导性。它看起来像Soprano.sing() 将被调用,而Singer.sing() 将根据mySoprano1 的声明类型被调用。
  • 好吧,它只是调用 sing() 函数。第一次是基类,然后是子类。所以如果我想使用 chlid 类名调用基类的 sing() 怎么办我能像 Soprano.sing() 那样做吗?它会调用超类的函数 sing()。
  • 我想我不是这个例子的粉丝。
  • @RathoreSunny - 我不确定我是否遵循你想要的。 ?
【解决方案2】:

我能想到的一点是,如果您使用类引用而不是对象,JVM 根本不需要创建 new 对象来访问该静态变量。这是提高性能的良好编程实践。

【讨论】:

  • 不过,您不需要对象,只是一个参考。 Foo foo = null; foo.myStatic; 可以正常工作(并且不会抛出 NPE)。
【解决方案3】:

如果你写MyClass.staticVariablemyObject.staticVariable 更能自我记录。它告诉查看代码的人staticVariableMyClass 的属性,而不是myObject,后者是该类的特定实例。

【讨论】:

  • 此外,编译器生成完全相同的代码,因为在编译时已经清楚您所指的静态变量。
猜你喜欢
  • 2016-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-05
  • 2015-08-14
相关资源
最近更新 更多