2015-09-05 26 views
4

我正在阅读Java tutorials从开始,我有一个关于字段或变量的关键字static的问题。正如Java所述herestatic关键字如何在Java中工作?

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

就这样,我想,如果你有一个对象(在这种情况下,类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我齿轮的值设置为七:

bicycle1.setGears(7); 

那么如果我尝试获取齿轮的值我n bicycle2我应该获得与我在bicycle1上设置的值相同的值,对吗?

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

好了,这里是我的疑惑因为Java在这上面我把帖称:

这告诉编译器恰好有一个存在

这个变量的副本

此副本存储在哪里?对象如何访问该副本?这个副本何时创建?

+2

[JVM如何手的可能重复(静态变量?)(http://stackoverflow.com/questions/27229714/how-jvm-handles-static-variable) –

+0

顺便说一句,你通常不应该从实例调用静态方法/属性。我不知道为什么编译器允许它 – Dici

+0

@Dici如果我使用它们,请问你能解释一下它可能产生的问题吗? –

回答

6

该副本存储在哪里?

副本(静态变量)存储在Permanent Geneneration部分,但如果使用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

+0

清除并完成。谢谢!只是怀疑:当你说“有一个类的参考”,你是否提到它可以访问永久生成部分? –

+0

*“如果您使用Java8的永久代部分不再存在”* ...我不相信这是正确的。相反,自Java 8以来,PermGen的大小自动管理,管理员不再需要关注自己的调整。 “*您创建的每个类(对象)实例都有对该类的引用。*”......不知道这意味着什么。 – scottb

+0

是的,参考可以访问永久生成部分。但是,PermGen部分已经在Java8中被删除,并已被Metaspace取代,请参阅[link](http://stackoverflow.com/questions/18339707/permgen-elimination-in-jdk-8/23388882#23388882) – m0bius

1

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

class Bicycle{ 
    public static int gears = 7; 

    //Methods to set and get gears 
} 

您可以访问静态方法这样

Bicycle.gears; 

所以,有java的声明只是一个自行车类,当你实例化一个类是建立自行车的一个实例与声明的所有静态属性。

+0

是的我知道如果我只想访问'static'变量,我只需要一个'Bicycle'类的实例。这只是我对Java教程的理解的一个例子,如果我有两个同一类的实例(对象),那么这两个对象的值都是相同的(不需要直接在第二个对象中输入值) )。所以我想知道的是我在问题底部提出的问题。创建副本的时间和位置以及对象如何访问该副本。我的意思是如果你有一个以上具有相同“静态”值的类的对象。 –

+0

@ Error404你需要明白的是'静态'变量不是对象的一部分。永远。它们是* class *的一部分,存储在* class *中,并通过* class *访问。 – Darkhogg

0

该副本存储在哪里?

静态变量存储在一些静态存储(permgen,我相信),你不应该打扰它。

何时创建此副本?

上课时被访问的第一时间(由类加载器加载)时创建,永远不会被删除(除非类被卸载)

对象如何进入该副本?

实例具有对其类的引用,并且类对所有变量都很敬畏。 C结构如何放置在内存中是特定于实现的细节。

由于静态变量被绑定到类,而不是实例,所以甚至不需要实例化类来访问它们。 MyClass.myStaticVar是好的。

2

就这样,我想,如果你有一个对象(在这种情况下,类自行车的 实例)和它里面的字段那么它的静态值就是这个值,无论你是参加bicycle1还是 bicycle2,它的静态值都是相同的。我是否 错误或我明白了吗?

当你实例在Java类的第一次,在JVM创建两件事情

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

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

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

  • 静态字段属于类对象,而不是对任何实例
  • 一个静态方法:

    通常,但将static关键字为表示“独立任何实例的”是有用通过类对象调用并且具有任何实例

  • 的静态成员的类实例是不依赖于任何其他情况下,不直接访问
+0

非常有帮助!谢谢! –