在这里。假设我有这个课程
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中的内容是否会在foo
和bar
中重复?
答案 0 :(得分:6)
没有。初始化类时,静态变量被分配一次。来自Java Language Specification, §8.3.1.1 static
fields:
如果一个字段被声明为static,那么无论该类最终可以创建多少个实例(可能为零),都只存在该字段的一个化身。初始化类(§12.4)时,会生成静态字段(有时称为类变量)。
请注意,这指的是字段本身,而不是字段可能包含的任何值。除非声明字段为final
,否则您可以一个接一个地为其指定值。特别是,每次创建实例时,您都可以[误]使用构造函数为字段赋值。通常,应避免在构造函数中指定静态字段。 (有一些例外,例如使用静态字段来计算实例对象创建。)
您可以使用类名或使用对实例的引用来访问静态字段。 1 因此,以下内容都是等效的(提供foo
和bar
是类型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)
不,因为foo
和bar
甚至没有ArrayList [1] 。它是静态的,这意味着它属于类,因此您可以像这样访问它:
EpicClass.arylst.add("test"); // or do whatever you want
[1]嗯,从技术上讲,你可以做foo.arylst
,但你不应该这样做;这是滥用静态成员,它也会给你一个警告
答案 3 :(得分:1)
不,这是静态变量的重点。它们存在于类级别而不是实例级别,因此实例不包含数据成员的自己的“副本”。
答案 4 :(得分:1)
您可以访问EpicClass.arylst
或foo.arylst
或bar.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)
没有。每次创建类的新实例时都不会创建静态变量。此外,它还为所有实例保留相同的值。 (如果您创建了多个实例)。
我们还可以说 “静态变量不会改变/代表对象的状态” 。 如果我在这里错了,请纠正我。