static关键字如何在Java中工作?

时间:2015-09-05 21:41:24

标签: java

我从头开始阅读Java tutorials,我对字段或变量上的static关键字有疑问。正如Java所说here

  

Class Variables (Static Fields) 类变量是使用static修饰符声明的任何字段;这告诉编译器这个变量只有一个副本存在,无论该类被实例化多少次。定义特定类型自行车齿轮数的字段可以标记为静态,因为从概念上讲,相同数量的齿轮将适用于所有实例。

有了这个,我想如果你有一个对象(在这种情况下,是一个类Bicycle的一个实例)并且它内部的一个字段是static那么,如果你是refearing到bicycle1bicycle2,其静态将具有相同值的字段。我错了还是我理解得很好?

我的意思是,如果我有:

Bicycle bicycle1 = new Bicycle();
Bicycle bicycle2 = new Bicycle();

在课程Bicycle中,我有一个static字段,如:

class Bicycle{
   static int gears;

   //Methods to set and get gears
}

bicycle1中,我将齿轮值设置为7:

bicycle1.setGears(7);

然后,如果我尝试在bicycle2中获取齿轮的值,我应该得到与bicycle1上设置的值相同的值,对吗?

System.out.println(bicycle2.getGears()); //7

嗯,这是我怀疑的地方,因为Java在我上面的引文中说:

  

这告诉编译器存在这个变量的正好一个副本

此副本存储在何处?对象如何访问该副本?该副本何时创建?

4 个答案:

答案 0 :(得分:9)

此副本存储在何处?

副本(静态变量)存储在“永久生成”部分中,但如果使用Java8,则“永久生成”部分不再存在。 静态变量和静态方法是反射数据的一部分,反射数据是与类相关的数据,而不是与实例相关的。

对象如何访问该副本?

您创建的每个类(对象)实例都引用了该类。

何时创建此副本?

它是在加载类时在运行时创建的:这是在首次引用类时由JVM的类加载器完成的。

静态变量属于该类,而不属于该类的实例。 你的直觉是正确的 - 无论你创建多少个对象,你只有一个副本。

您可以使用类的名称访问静态变量,如下例所示:

class Static {

    static int staticField;

}

public class UseStatic {

    public static void main(String[] args) {

        System.out.println(Static.staticField);

    }
}

静态字段对于创建某种类常量非常有用。

最后,要轻松初始化特定类的静态字段,您可以使用Static Initialization Blocks

来源:关于java的大学课程,java official documentation

答案 1 :(得分:3)

  

有了这个,我想如果你有一个对象(在这种情况下,一个   自行车类的实例)和它内部的一个字段   静止然后,独立于你是否正在自行车1或   bicycle2,其静态将具有相同值的字段。我   错了还是我理解得很好?

首次在Java中实例化类时,JVM会创建两件事

  • 一个实例。将一组非静态字段分配到堆上,用于您创建的每个实例。这些实例字段与所有其他实例分开(并用于表示其对象的状态)。

  • 一个Class对象。 Java中的每个类都有一个且只有一个Class对象......无论创建多少个实例。例如,类String的Class对象是Class<String>(表示为文字String.class)。您可以将类的静态字段视为属于Class对象。 Class对象的生命周期独立于类实例的生命周期;只要JVM进程正在运行,就会存在类对象(因此,它们的静态字段也存在很长时间)。

由于类只有一个Class对象,并且由于类的所有实例共享同一个Class对象,因此类的静态字段由所有存在的类实例共享。

通常,将static关键字视为“独立于任何实例”意义非常有用:

  • 静态字段属于Class对象,而不属于任何实例
  • 通过Class对象调用静态方法,并且无法直接访问任何实例
  • 静态成员类实例不依赖于任何其他实例

答案 2 :(得分:1)

java中的静态变量存储在类中,您不需要创建它的实例来访问它们。

class Bicycle{
   public static int gears = 7;

   //Methods to set and get gears
}

您可以像这样访问静态方法

Bicycle.gears;

所以,只有一个在java上声明的Bicycle类,当你实例化一个类时,它会创建一个自行车实例并声明所有静态属性。

答案 3 :(得分:0)

  

此副本存储在何处?

静态变量存储在一些静态存储器中(我相信permgen),你不应该为此烦恼。

  

何时创建此副本?

它们是在第一次访问类时创建的(由类加载器加载)并且永远不会删除(除非卸载类)

  

对象如何访问该副本?

Instance引用了它的类,而class对它的所有变量都有敬意。如何在内存中放置C结构是特定于实现的细节。

由于静态变量绑定到类而不是实例,因此您甚至不需要实例化类来访问它们。 MyClass.myStaticVar没问题。