Разница между loadClass (имя строки) и loadClass (имя строки, логическое разрешение) - PullRequest
7 голосов
/ 25 марта 2011

В чем разница между loadClass(String name) и loadClass(String name, boolean resolve)?

Единственное различие, которое я знаю, это loadClass(String name, boolean resolve) вызывает findLoadedClass (String), если параметр resolve имеет значение true?

Так когда же значение true или false передается параметру resolve?
Я много путаю между этими двумя функциями.

Спасибо.

Ответы [ 3 ]

3 голосов
/ 25 марта 2011

Параметр resolv определяет, связан ли загруженный класс или нет.Во время связывания статические константы инициализируются и им выделяется память.Кроме того, класс проверен на правильность, и, возможно, будут разрешены ссылки на другие классы.

Это может быть полезно, например, если вы хотите загрузить новый класс, который может быть поврежден ихотите, чтобы JVM выдавала ошибки проверки в случае, если класс содержит ошибки.

1 голос
/ 10 июля 2011

Вы можете попробовать.

public class Test3  {

    static{
         new Test();
    }   
}

После компиляции измените класс теста с конкретного класса на интерфейс. Но оставьте ссылку Test3 на конкретный класс Test.Then, если resolver равен false, JVMне найду эту ошибку. Это очень интересно.На самом деле, Class someClass1= Class.forName("Test3",false,cls) также не разрешит Test3. Это означает, что не будет выдано никакой ошибки.

Но если вы установите значение true в подклассе или Class.forName("Test3"), то JVM во время выполнения найдет ошибку ссылки на класс.

Exception in thread "main" java.lang.InstantiationError: Test
    at Test3.<clinit>(Test3.java:6)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:169)

Для справки, Спецификация языка Java - 12.3 Связывание классов и интерфейсов объясняет, что делает resolClass.

12.3 Связываниеклассов и интерфейсов Связывание - это процесс принятия двоичной формы класса или типа интерфейса и объединения ее в состояние времени выполнения виртуальной машины Java, чтобы его можно было выполнить.Класс или тип интерфейса всегда загружается до того, как он будет связан.Связывание включает три различных действия: проверка, подготовка и разрешение символьных ссылок . Точная семантика связывания дана в главе 5 Спецификации виртуальной машины Java, второе издание.Здесь мы представляем обзор процесса с точки зрения языка программирования Java.

12.3.3 Разрешение символических ссылок Двоичное представление класса или интерфейса ссылается на другие классы и интерфейсы и их поля,методы и конструкторы символически, используя двоичные имена (§13.1) других классов и интерфейсов (§13.1). Для полей и методов эти символьные ссылки включают в себя имя класса или типа интерфейса, который объявляет поле илиметод, а также имя поля или самого метода вместе с соответствующей информацией о типе.Прежде чем использовать символическую ссылку, она должна пройти разрешение, при котором символическая ссылка проверяется на правильность и, как правило, заменяется прямой ссылкой, которая может быть более эффективно обработана, если ссылка используется повторно.

Есливо время разрешения возникает ошибка, затем будет выдана ошибка.Чаще всего это будет экземпляр одного из следующих подклассов класса IncompatibleClassChangeError , но он также может быть экземпляром некоторого другого подкласса IncompatibleClassChangeError или даже экземпляром самого класса IncompatibleClassChangeError.Эта ошибка может быть выдана в любой точке программы, которая использует символическую ссылку на тип, прямо или косвенно:

IllegalAccessError : Обнаружена символическая ссылка, которая указывает использование или назначениеполя, или вызова метода, или создания экземпляра класса, к которому у кода, содержащего ссылку, нет доступа, поскольку поле или метод были объявлены как закрытые, защищенные или доступ по умолчанию (не общедоступный), илипотому что класс не был объявлен публичным.Это может произойти, например, если поле, которое первоначально объявлено как общедоступное, изменяется на частное после того, как был скомпилирован другой класс, который ссылается на это поле (§13.4.6).

InstantiationError : Обнаружена символическая ссылка, которая используется в выражении создания экземпляра класса, но экземпляр не может быть создан, поскольку ссылка ссылается на интерфейс или абстрактный класс.Это может произойти, например, если класс, который изначально не является абстрактным, изменяется на абстрактный после того, как был скомпилирован другой класс, который ссылается на рассматриваемый класс (§13.4.1).

NoSuchFieldError: Обнаружена символьная ссылка, которая относится к конкретному полю определенного класса или интерфейса, но класс или интерфейс не содержат поля с таким именем.Это может произойти, например, если объявление поля было удалено из класса после того, как был скомпилирован другой класс, который ссылается на поле (§13.4.7).

NoSuchMethodError : Обнаружена символическая ссылка, которая относится к конкретному методу определенного класса или интерфейса, но класс или интерфейс не содержат метод этой сигнатуры. Это может произойти, например, если объявление метода было удалено из класса после того, как был скомпилирован другой класс, который ссылается на метод (§13.4.11). Кроме того, UnsatisfiedLinkError (подкласс LinkageError ) может быть выдан, если класс объявляет собственный метод, для которого не может быть найдена реализация. Ошибка произойдет, если метод используется, или ранее, в зависимости от того, какую стратегию разрешения использует виртуальная машина (§12.3).

1 голос
/ 25 марта 2011

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

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