Правда ли, что объект java.lang.Class создается при загрузке Java-класса, даже до того, как будет создан экземпляр? - PullRequest
0 голосов
/ 24 февраля 2012

Предположим, у классов есть код, подобный следующему:

class C {
    public static void show() {
    }
}

class CTest {
    public static void main (String[] args) {
        C.show();
    }
}

Тогда будет совершенно законно сделать вывод, что при обращении к классу C для доступа к статическому методу show() здесь, за сценой Javaна самом деле вызывает show() метод через отражение Java?

Т.е. действительно ли он делает что-то подобное

Class test = Class.forName(C);
test.show();

для вызова статических методов?

Если нет, то как на самом деле он вызывает статические методы без создания объектов?

Если приведенное выше объяснение верно, то как мы оправдаем утверждение, что «статические члены связаны только с классами, а не объектами», когда мы фактически вызываем метод через java.lang.Class объект?

Ответы [ 4 ]

3 голосов
/ 24 февраля 2012
  1. JVM не нужно делать ничего похожего на Class.forName() при вызове статического метода, потому что когда класс вызывает , метод инициализируется (или когда методзапускается в первый раз, в зависимости от того, где находится вызов статического метода), эти другие классы ищутся, и ссылка на код статического метода устанавливается в пул данных, связанных с этим вызывающим классом.Но в какой-то момент во время этой инициализации, да, эквивалент Class.forName() выполняется для поиска другого класса.

  2. Это показательный семантический аргумент.С таким же успехом можно сказать, что это усиливает стандартную линию, согласно которой статический метод связан с классом , а не с любым экземпляром класса.

1 голос
/ 24 февраля 2012

Вы можете поместить оператор println в ctor, чтобы проверить, вызывается он или нет:

class C {
    public static void show () {
        System.out.println ("static: C.show ();");
    }

    public C () {
        System.out.println ("C.ctor ();");
    }

    public void view () {
        System.out.println ("c.view ();");
    }

}

public class CTest
{
    public static void main (String args[])
    {
        System.out.println ("static: ");
            C.show ();
        System.out.println ("object: ");
            C c = new C ();
            c.view ();
            c.show (); // bad style, should be avoided
    }
}
1 голос
/ 24 февраля 2012

Для дополнительной информации:

Вызываемый класс будет загружен, когда на него впервые ссылается вызывающий код.т. е. JVM разрешает и загружает класс только в той строке кода, в которой он в первую очередь нуждается.Вы можете проверить это, используя аргумент JVM "-verbose: class" и пройдя через отладчик.

Для загрузки класса будет вызван ClassLoader.loadClass (String name).

1 голос
/ 24 февраля 2012

JVM делит память, которую она может использовать, на разные части: одну часть, где хранятся классы, и одну для объектов. (Я думаю, что могла быть третья часть, но я не совсем уверен в этом прямо сейчас).

В любом случае, когда объект создается, java ищет соответствующий класс (например, чертеж) и создает его копию -> вуаля, у нас есть объект. Когда вызывается статический метод, выполняется метод класса в первой части памяти, а не метод объекта во второй части. (поэтому нет необходимости создавать экземпляр объекта).

Кроме того, для отражения требуется много ресурсов, поэтому использование его для вызова статических методов может значительно повлиять на производительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...