Является экземпляром класса, автоматически созданного при первом вызове статического метода

Я хотел бы знать, есть ли у вас класс с только статическими методами, действительно ли экземпляр класса создается где-то, когда вы вызываете 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");