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

我正在从头开始阅读Java教程 ,我对字段或变量上的static关键字有疑问。 正如Java 在这里所说:

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

有了这个,我想如果你有一个对象(在这种情况下,是一个类Bicycle一个实例)和它内部的一个字段,那么它是static ,如果你正在为bicycle1或者bicycle2 ,它的静止字段将具有相同的价值。 我错了还是我理解得很好?

我的意思是,如果我有:

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

在class级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在上面提到的引用中所说:

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

这个副本存放在哪里? 对象如何访问该副本? 什么时候创建这个副本?

这个副本存放在哪里?

副本(静态变量)存储在Permanent Geneneration部分中,但如果使用Java8,则永久生成部分不再存在。 静态变量以及静态方法是reflection数据的一部分 – 类相关数据而非实例相关。

对象如何访问该副本?

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

什么时候创建这个副本?

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

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

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

 class Static { static int staticField; } public class UseStatic { public static void main(String[] args) { System.out.println(Static.staticField); } } 

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

最后,要轻松初始化特定类的静态字段,可以使用静态初始化块 。

资料来源 :关于java的大学课程, java官方文档

有了这个,我想如果你有一个对象(在这种情况下,是一个类Bicycle的一个实例)和它内部的一个字段,那么它是静态的,如果你正在为自行车1或者自行车2加油,它的静止字段将具有相同的价值。 我错了还是我理解得很好?

当您第一次在Java中实例化一个类时,JVM会创建两件事

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

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

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

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

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

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

 class Bicycle{ public static int gears = 7; //Methods to set and get gears } 

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

 Bicycle.gears; 

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

这个副本存放在哪里?

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

什么时候创建这个副本?

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

对象如何访问该副本?

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

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