Является экземпляром класса, автоматически созданного при первом вызове статического метода
Я хотел бы знать, есть ли у вас класс с только статическими методами, действительно ли экземпляр класса создается где-то, когда вы вызываете 1-й статический метод?
Это несколько сложно понять с точки зрения управления памятью, поскольку вы никогда не вызываете конструктор или не создаете экземпляр метода явно.
Если экземпляр создается, я хотел бы лучше понять, где этот экземпляр живет и как долго.
Ответы
Ответ 1
Нет. Вызов метода static
не требует (или создает) экземпляр class
. См. Также JLS-8.4.3.2 static
методы, в котором говорится (частично)
Метод, объявленный static
, называется методом класса.
...
Метод класса всегда вызывается без ссылки на конкретный объект.
Ответ 2
Скажите, что у вас
static class Foo
{
static Bar bar = new Bar();
static int func(){ ... }
}
очевидно, что объект Foo
не будет создан для вызова func()
.
Однако класс Foo
должен быть загружен в память; и к приложению есть объект, соответствующий классу, который может называться Foo.class
или Class.forName("Foo")
.
Загруженный класс еще не инициализирован. Когда вы вызываете статический метод в первый раз, класс инициализируется; некоторое "пространство" выделяется для статических переменных, а статический код инициализатора (например, new Bar()
) выполняется.
Это "пространство" не видимо для приложения как объекта; но это также в структуре данных памяти, которая касается сборки мусора (и других объектов, на которые она ссылается, например bar
)
Класс и "пространство" подходят только для GC, когда загрузчик классов, загружающий класс, имеет право на GC. Для обычных приложений командной строки это никогда не происходит. Но для многих других приложений класс GC важен, и загрузка классов должна быть тщательно выполнена.
Ответ 3
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");