假设我有一个静态方法增量:
public class StaticTest {
private static int no = 0;
public static void increment()
{
no++;
}
}
当我使用StaticTest.increment()
语法调用increment时,该类是否会被实例化?如果堆上没有该类型的对象,该怎么办?
答案 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
实例化实例,除非您创建了其中一个,否则您尚未创建实例。