我想知道你是否有一个只有静态方法的类,当你调用第一个静态方法时,是否会在某个地方创建一个类的实际实例?
在内存管理方面理解这有点令人困惑,因为你从未实际调用构造函数或显式创建方法实例。
如果确实创建了一个实例,我想更好地了解这个实例的存在位置和持续时间。
答案 0 :(得分:13)
没有。调用static
方法不需要(或创建)class
的实例。另请参阅JLS-8.4.3.2 static
methods,其中(部分)
声明为
static
的方法称为类方法。
...
总是在不引用特定对象的情况下调用类方法。
答案 1 :(得分:6)
说你有
static class Foo
{
static Bar bar = new Bar();
static int func(){ ... }
}
显然,不会为调用Foo
创建func()
对象。
但是,类Foo
需要加载到内存中;对于应用程序,有一个对应于该类的对象,可以称为Foo.class
或Class.forName("Foo")
。
尚未初始化已加载的类。当你第一次调用静态方法时,该类被初始化;一些"空间"为静态变量分配,并执行静态初始化代码(如new Bar()
)。
这个"空间"应用程序不可见作为对象;但它也是一个内存数据结构,它涉及垃圾收集(以及它引用的其他对象,如bar
)
当加载该类的类加载器符合GC条件时,该类和" space"只适用于GC。对于通常的命令行应用程序,从未发生过。但对于许多其他应用程序,GC类很重要,需要仔细完成类加载。
答案 2 :(得分:4)
static
方法属于该类,而不属于对象引用。您可以调用static
方法并忘记在创建正在使用的类的对象引用时浪费内存,但这并不会发生。在对象引用上调用static
方法时,会在主题上收到编译器警告。您甚至可以在所需类的变量上调用static
方法,此变量可以是null
,static
方法将被调用,没有任何问题。
public class Foo {
public static void sayHello(String name) {
System.out.println("Hello " + name);
}
}
//works, no instance of Foo was created
Foo.sayHello("AlexVPerl");
Foo foo = new Foo();
//works, compiler raises a warning here
foo.sayHello("AlexVPerl");
foo = null;
//works, compiler raises a warning here
//and as you can see, it doesn't matter if the instance is null
foo.sayHello("AlexVPerl");