Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 创建类的新实例时,类中的静态变量是否重复?_Java_Oop - Fatal编程技术网

Java 创建类的新实例时,类中的静态变量是否重复?

Java 创建类的新实例时,类中的静态变量是否重复?,java,oop,Java,Oop,这儿,那儿。假设我上这门课 public class EpicClass{ public static ArrayList<String> arylst = new ArrayList<>(); public String field1; public String field2: } 数组列表中的内容是否会在foo和bar中重复?否,因为foo和bar甚至没有数组列表。它是静态的,这意味着它属于类,因此您可以这样访问它: EpicClass.

这儿,那儿。假设我上这门课

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

    public String field1;
    public String field2:
}

数组列表中的内容是否会在
foo
bar
中重复?

否,因为
foo
bar
甚至没有数组列表。它是静态的,这意味着它属于类,因此您可以这样访问它:

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

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

否。初始化类时,静态变量只分配一次。从:

如果一个字段被声明为静态的,那么不管最终创建了多少个类实例(可能为零),该字段只存在一个化身。静态字段(有时称为类变量)在初始化类()时具体化

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

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

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


1当然,只要字段是可访问的。

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

您可以访问
EpicClass.arylst
foo.arylst
bar.arylst
。它们都指向同一个物体。ArrayList本身是
EpicClass

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

运行以下代码将打印
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));
}
EpicClass foo=新的EpicClass();
EpicClass bar=新EpicClass();
foo.arylst.add(“Hi”);

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

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

不,静态变量只有一块存储空间,不管它是抢占型还是对象型,不管创建了多少个对象。即使静态数据初始化也只发生一次。 我可以举一个例子来证明这个概念。我在上面的程序中做了一些小的修改。我正在初始化我的自定义对象来代替“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:

EpicClass对象创建了2次('foo'和'bar')。但此类静态变量book仅初始化一次。但非静态变量book1初始化2次(对于'foo'和'bar')。这意味着所有实例共享静态变量,但所有实例都有自己的非静态变量副本。

静态变量如何从类外访问(或没有所述类的任何实例)?这表明静态字段如何在“实例之间”操作?
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));
}
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();
    }

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