2012-06-20 2 views
2

У меня есть проект, который требует динамического создания классов во время выполнения, где единственной доступной информацией является имя класса в форме String. Я тестирую прямо сейчас с помощью некоторых мертвых простых методов библиотеки Reflection, но мой вопрос в том, почему я должен предоставить полное имя класса, если классы, которые я пытаюсь «динамически» загружать, находятся в одном каталоге? Я использую linux, без среды разработки, только все классы, которые я пытаюсь вызывать в том же каталоге, без каких-либо объявлений пакетов. Должен ли я настраивать систему пакетов для использования Reflection? Вот этот небольшой фрагмент кода ....Библиотека Java Reflection - с использованием Class.forName() без информации о пакете

public class ReflectionTest { 
    public static void main(String[] args) { 
     try { 
      Class nodeClass = Class.forName("Node"); 
      System.out.println(nodeClass.toString()); 
     } catch (ClassNotFoundException cnfe) { 
      System.out.println("Error"); 
     } 
    } 
} 

Теперь это вызывает ошибку. Но когда я создаю экземпляр узла, а затем получаю его полное имя класса с Node.getClass().getName(), я просто получаю «Узел» взамен. Поэтому я не понимаю, почему библиотека Reflection не работает так же, как вызывать JVM с помощью «java», где, если имя пакета не указано, оно просто выглядит в том же каталоге. Я не уверен, как использовать эту библиотеку с пользовательскими классами, если ни один из моих классов не имеет имя связанного пакета.

+0

Какую именно команду вы используете для запуска 'ReflectionTest'? – matts

ответ

2

Ваш код должен работать, как описано. То есть, если вы можете позвонить new Node(), вы также сможете позвонить по телефону Class.forName("Node"). Я только что попробовал это с классом без пакетов, чтобы проверить, и все работает так, как ожидалось.

Есть Node.class Доступно в classpath? Вы можете заставить это работать, добавив текущий каталог в путь к классам.

+0

Вот что я * думал * ха-ха, это действительно меня смущает, и да, все скомпилировано, и я могу создавать объекты Node. Я буду продолжать играть с ним, но это странно ... – MassStrike

1

Прежде всего, вам необходимо убедиться, что классы, которые вы пытаетесь загрузить в пути к классам, поэтому при запуске JVM, попробуйте добавить текущую папку к нему: java -cp . ReflectionTest

Концепция пакетов чтобы ваши вещи были организованы и чтобы можно было повторно использовать имена. Предоставление полного имени гарантирует, что вы используете правильный класс узла, а не, например, org.w3c.dom.Node или что-то подобное, которое будет неявно отправлено с помощью java.

1

Это работает для меня, используя точные ReflectionTest.java выше и следующие Node.java:

public class Node { } 

ли вы компилировать Node.java, а также ReflectionTest.java? Поскольку класс ReflectionTest не имеет зависимости от времени компиляции в классе Node, javac не будет автоматически компилировать Node.class при компиляции ReflectionTest.class.

1

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

Если каталог, содержащий Node.class, находится в пути к классу, приведенный выше код должен работать.

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

2

Название пакета является неотъемлемой частью системы именования java. Однако, если ваш класс не объявляет пакет, он находится в корневом пакете, код, который вы опубликовали, должен работать.

Мое предположение: каталог на самом деле не находится в CLASSPATH. Попробуйте добавить текущий каталог (./) и убедиться, что он на самом деле является текущим каталогом, или явно указать путь (абсолютный путь) в вашем CLASSPATH. Обратитесь к документам, чтобы узнать, как установить CLASSPATH (параметры среды, jvm, время выполнения - ваши варианты).