java.lang.ClassNotFoundException для указанного класса

У меня в основном есть следующее утверждение

Class booki = Class.forName("Book");

который бросает java.lang.ClassNotFoundException исключение

когда я использую полный путь, как Class booki = Class.forName("javatests.Book"); все в порядке.

Основной класс и класс Book находятся в одном пакете, я также пытался использовать import static javatests.Book.*; но все равно выдает исключение, если я не установил полный путь javatests.Book, Может кто-нибудь объяснить мне, почему?

5 ответов

Решение

Class.forName разрешает полное имя класса в класс. Поскольку метод не знает, где он вызывается ни из пакета вызывающего класса, ни из imports в вызывающем классе играют любую роль.

Из документов Class#forName

 public static Class<?> forName(String className)
                    throws ClassNotFoundException

Параметры:
className - полное имя нужного класса.

Так что это не скинут ClassNotFoundException

Class booki = Class.forName("javatests.Book");  

Например, не нужно импортировать java.lang.* пакет в программе Java, но для загрузки класса Thread от java.lang пакет нужно написать

Class t = Class.forName("java.lang.Thread");

приведенный выше фрагмент кода возвращает дескриптор класса времени выполнения для класса с именем java.lang.Thread

JLS предоставляет следующее описание:

Поиск класса всегда выполняется от имени ссылающегося класса и выполняется через экземпляр ClassLoader, Учитывая полное имя класса, этот метод пытается найти, загрузить и связать класс.

JDK использует один экземпляр ClassLoader который ищет набор корней дерева каталогов, указанных в переменной среды CLASSPATH; и, очевидно, он не знает о месте (пакете), которое он назвал. Вот почему ему нужно полное имя.

Во-первых, класс Book должен быть в пакете javatests.
JVM загружает класс по имени через путь к классу. В пути к классам нет класса с именем "Книга". Таким образом, JVM дает вам ClassNotFoundException, когда оправдывает Class.forName("Книга"). Но Class.forName("javatests.Book")'сообщает JVM, что класс с именем' Book 'находится в пакете'javatests'. Таким образом, JVM может найти его и загрузить.

Надеюсь мой ответ полезен:)

Вам всегда нужно квалифицированное имя класса, если оно не внутри одного пакета. Если я определю класс foo в моем пакете, я могу вызвать метод Class testClass = Class.forName("foo") но я не могу позвонить Class testClass = Class.forName("SecureRandom"); даже если я импортирую SecureRandom. Вот как работает эта функция. Вероятно, у него есть ярлык, где он пытается найти что-то внутри локальных пакетов, но мало что делает за этим.

Другие вопросы по тегам