使用静态方法时,每个类都会实例化吗?

jam*_*ean 5 java static

假设我有一个静态方法增量:

public class StaticTest {
    private static int no = 0;

    public static void increment()
    {
        no++;
    }
}
Run Code Online (Sandbox Code Playgroud)

当我使用StaticTest.increment()语法调用increment时,该类是否会被实例化?如果堆上没有该类型的对象,该怎么办?

T.J*_*der 6

当我使用StaticTest.increment()语法调用increment时,该类是否会被实例化?

本身被加载(由类加载器),如果它尚未加载.如果已加载,则不会再次加载.没有创建类的实例(该类的类型的对象),因为您还没有创建任何实例.

假设调用的所有代码StaticTest.increment()都使用相同的类加载器(通常就是这种情况),那么有多少不同的代码调用该静态方法并不重要,只使用该类的单个副本.他们都分享它.例如:

// Some bit of code somewhere
StaticTest.increment();

// Another bit of code somewhere else
StaticTest.increment();

// A third bit of code in yet another place
StaticTest.increment();
Run Code Online (Sandbox Code Playgroud)

一旦所有这些都运行,no私有静态成员in StaticTest具有值3.

如果堆上不存在该类型的类,该怎么办?

然后classloader加载它.


将代码与此对比(无static):

public class NonStaticTest {
    private int no = 0;

    public void increment()
    {
        no++;
    }

    public int getNo() // So we can see the results
    {
        return no;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我们不能这样做:

NonStaticTest.increment(); // WRONG, fails with error saying `increment` is not static
Run Code Online (Sandbox Code Playgroud)

我们这样做:

NonStaticTest instance = new NonStaticTest();
instance.increment();
System.out.println(instance.getNo()); // "1"
Run Code Online (Sandbox Code Playgroud)

第一时间码这样做,该NonStaticTest班是由类加载器加载.然后,new NonStaticTest()表达式创建一个类的实例,该实例具有一个no成员.在第二时间码这样做,NonStaticTest已经被加载,所以它不会重新加载.然后new NonStaticTest()表达式创建该类的第二个实例.

如果我们有三位代码全部执行上述操作,则每个代码都会看到"1",因为no它特定于类的实例而不是附加到类本身.