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

时间:2014-05-01 09:06:18

标签: java static

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

public class StaticTest {
    private static int no = 0;

    public static void increment()
    {
        no++;
    }
}

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

3 个答案:

答案 0 :(得分:6)

  

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

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

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

// 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();

所有这些广告投放后,no中的StaticTest私有静态成员的值为3

  

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

然后classloader加载它。


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

public class NonStaticTest {
    private int no = 0;

    public void increment()
    {
        no++;
    }

    public int getNo() // So we can see the results
    {
        return no;
    }
}

现在,我们不能这样做:

NonStaticTest.increment(); // WRONG, fails with error saying `increment` is not static

我们这样做:

NonStaticTest instance = new NonStaticTest();
instance.increment();
System.out.println(instance.getNo()); // "1"

第一个时间代码执行此操作,类NonStaticTest类由类加载器加载。然后,new NonStaticTest()表达式创建类的实例,其中包含no成员。 第二个时间码执行此操作,NonStaticTest已加载,因此未再次加载。然后new NonStaticTest()表达式创建该类的第二个实例

如果我们有三位代码都在执行上述操作,那么每个代码都会看到“1”,因为no特定于类的实例而不是附加到班级本身。

答案 1 :(得分:2)

你必须明确区分两件事:

  • 类,它们是“自定义类型”(我在这里简化)
  • 对象,它们是这些类的实例

类由类加载器加载一次,而每次调用new ClassName()时都会创建类的对象(如果类被称为ClassName)。

现在,回到你的问题:使用static关键字使你的声明独立于你班级的任何实例(对象)。

因此,当您使用StaticTest.increment()时,不会创建类StaticTest的对象(并且不需要任何对象)。

答案 2 :(得分:1)

使用new StaticTest实例化实例,除非您创建了其中一个,否则您尚未创建实例。