【问题标题】:Performance difference between static and instance variables静态变量和实例变量之间的性能差异
【发布时间】:2018-04-02 23:40:54
【问题描述】:

每个对象都有一个实例变量,每个对象都有自己的实例变量副本。

每个类一个静态变量,该类的每个对象共享同一个静态变量。

class MyStaticClass{
  private static int myStaticInt;

  public static int getMyStaticInt() {return myStaticInt;}
}

class MyInstanceClass{
  private int myNonStaticInt;

  public int getMyNonStaticInt() {return myNonStaticInt;}
}

两者之间有性能差异吗?打电话比打电话更贵吗?

int i = MyStaticClass.getMyStaticInt();

或:

int i = new MyInstanceClass().getMyNonStaticInt();

【问题讨论】:

  • 它们不等价,所以这个问题没有意义。

标签: java static instance instance-variables


【解决方案1】:

由于实例方法可以是多态的overridden,一个非常幼稚的JVM 实现必须至少最初使用virtual mehod table 来找到合适的方法来调用。然而,类本身是多态的,并且类方法不能被覆盖。因此,they have a simpler lookup mechanism

然而,现实世界的 JVM 非常聪明,可以判断哪些方法永远不会被覆盖并优化此查找。换句话说,除了最人为的、不存在 JVM 的实例之外,所有实例的性能都会有所不同。相反,使用静态方法来表示与整个对象类本身相关的功能,而不是与其单个实例相关的功能。

【讨论】:

    【解决方案2】:

    这不是性能问题。静态变量和实例变量有不同的用途。

    使用

    int i = new MyInstatnceClass().getMyNonStaticInt();
    

    几乎可以肯定是没用的,因为每次调用new MyInstatnceClass() 时,都会创建一个新的MyInstatnceClass 实例,并拥有一个新的myNonStaticInt 实例变量。由于您没有保留对已创建实例的引用,因此您无法两次检索相同的实例变量,这使其无用。

    如果您需要一个变量的单个副本在类的所有实例之间共享,static 变量是您的最佳选择。

    也就是说,后一个调用也更广泛,因为它涉及创建和初始化 MyInstatnceClass 类的实例(除了加载和初始化类,如果它是第一次访问该类)。

    另一方面,MyStaticClass.getMyStaticInt() 只加载和初始化类 MyStaticClass,如果它是该类的第一次访问。它不必创建该类的任何实例。

    【讨论】:

    • @Program-Me-Rev 更改变量名和getter方法不会影响我的回答。 int i = new MyInstatnceClass().getMyNonStaticInt(); 仍然没有意义。
    • 感谢@Eran 的回复。我犯了一个trypo错误。我的意思是int i = new MyInstatnceClass().getMyNonStaticInt();。你的回答回答了我的担忧,除了第一部分来自我道歉的错误。谢谢你的回答。
    • 虽然此答案中的信息是正确的,但它实际上并没有回答 OP:他们想知道静态或实例方法调用是否比另一个更高效/更便宜,而不是方法的类型有什么用。示例中的对象实例化不是他们想要评估的部分;它只是使其语法正确的必要样板。
    • @errantlinguist 我不同意你对这个问题的解释。OP 要求比较两行代码的性能,其中一行包含对象实例化,所以我认为没有理由忽略它。跨度>
    猜你喜欢
    • 2019-03-28
    • 1970-01-01
    • 1970-01-01
    • 2017-01-23
    • 1970-01-01
    • 1970-01-01
    • 2015-11-21
    • 1970-01-01
    • 2011-02-22
    相关资源
    最近更新 更多