是否在创建类的新实例时复制的类中是静态变量?

时间:2013-12-02 00:33:04

标签: java oop

在这里。假设我有这个课程

public class EpicClass{
    public static ArrayList<String> arylst = new ArrayList<>();

    public String field1;
    public String field2:
}

现在,如果我执行此代码:

/* ... Code which adds stuff to arylst ... */
EpicClass foo = new EpicClass();
EpicClass bar = new EpicClass();

ArrayList中的内容是否会在foobar中重复?

8 个答案:

答案 0 :(得分:6)

没有。初始化类时,静态变量被分配一次。来自Java Language Specification, §8.3.1.1 static fields

  

如果一个字段被声明为static,那么无论该类最终可以创建多少个实例(可能为零),都只存在该字段的一个化身。初始化类(§12.4)时,会生成静态字段(有时称为类变量)。

请注意,这指的是字段本身,而不是字段可能包含的任何值。除非声明字段为final,否则您可以一个接一个地为其指定值。特别是,每次创建实例时,您都可以[误]使用构造函数为字段赋值。通常,应避免在构造函数中指定静态字段。 (有一些例外,例如使用静态字段来计算实例对象创建。)

您可以使用类名或使用对实例的引用来访问静态字段。 1 因此,以下内容都是等效的(提供foobar是类型EpicClass):

EpicClass.arylst
foo.arylst
bar.arylst

(通过实例引用访问静态字段被认为是错误的,并且通常会生成编译器警告,但即使引用为null,它也能很好地工作,因为编译器会将其转换为第一种形式。 )仅从这个意义上说,“ArrayList中的东西”似乎在类的每个实例中都是重复的。但是,ArrayList只有一个实例,您只是通过(看似)不同的机制访问它。

1 当然可以访问该字段。

答案 1 :(得分:2)

不,无论是抢占类型还是对象类型,无论创建了多少对象,静态变量只有一个存储空间。甚至静态数据初始化只发生一次。       我可以举出证明这个概念的例子。我正在对你的上述程序进行小修改。代替'arylst'我正在初始化我的自定义对象。

class Book {
    Book(String s) {
        System.out.println("Book(" + s + ")");
    }
}

class EpicClass {
    public static Book book = new Book("static");
    public Book book1 = new Book("non-static");

    public String field1;
    public String field2;
}

public class Test {

    public static void main(String[] args) {
        EpicClass foo = new EpicClass();
        EpicClass bar = new EpicClass();
    }

}

和输出证明了上述概念。

O / P:

Book(static)
Book(non-static)
Book(non-static)

EpicClass对象创建了2次('foo'和'bar')。但是这个类的静态变量书只初始化一次。但是非静态变量book1初始化2次(对于'foo'和'bar')。它表示所有实例共享的静态变量,但所有实例都有自己的非静态变量副本。

答案 2 :(得分:1)

不,因为foobar 甚至没有ArrayList [1] 。它是静态的,这意味着它属于类,因此您可以像这样访问它:

EpicClass.arylst.add("test"); // or do whatever you want

[1]嗯,从技术上讲,你可以做foo.arylst,但你不应该这样做;这是滥用静态成员,它也会给你一个警告

答案 3 :(得分:1)

不,这是静态变量的重点。它们存在于类级别而不是实例级别,因此实例不包含数据成员的自己的“副本”。

答案 4 :(得分:1)

您可以访问EpicClass.arylstfoo.arylstbar.arylst。他们都指出同一个对象。 ArrayList本身是EpicClass中唯一的一个。

答案 5 :(得分:1)

静态变量将内化一次,并且只有一个共享内存分配给该类的所有实例。 静态变量是类变量,它不是特定于任何实例的。简单地说,我们可以说它对于所有类的实例都是通用的。每当更改来自类的一个实例的静态值时,修改后的值对该类的所有其他实例都是可见的。

答案 6 :(得分:1)

运行以下代码将打印Hi

EpicClass foo = new EpicClass();
EpicClass bar = new EpicClass();

foo.arylst.add("Hi");
for(int i = 0; i<bar.arylst.size(); i++) {
    System.out.println(bar.arylst.get(i));
}

正如其他人所说 - 静态变量被声明一次,属于该类。在类的一次实例中修改静态可变对象,也会在所有其他实例中修改它,因为静态对象属于,而不属于类的实例。

答案 7 :(得分:1)

没有。每次创建类的新实例时都不会创建静态变量。此外,它还为所有实例保留相同的值。 (如果您创建了多个实例)。

我们还可以说 “静态变量不会改变/代表对象的状态” 。 如果我在这里错了,请纠正我。