2014-12-08 1 views
0

В настоящее время я изучаю Reflection, и я видел большинство подобных сообщений в моем вопросе о стеке, но я не уверен, что они полностью отвечают на мой вопрос.Метод для повторения классов в пакете с использованием Reflection

Я хочу знать, есть ли у меня пакет в Eclipse, я могу использовать Reflection для повторения классов в пакете, чтобы найти, какой из них реализует интерфейс. Существует только 1 интерфейс, так что либо они реализуют его, либо нет.

Может ли кто-нибудь предоставить простой ясный пример того, как я могу это сделать? Мне сказали, что это просто невозможно, в то время как другие люди говорят, что это возможно с помощью Reflection.

Благодарим любого, кто мог бы помочь разобраться в этом вопросе.

ответ

2

API Reflection API не предоставляет возможности для итерации по классам в определенном пакете. Он концентрируется на открытии класса, когда он у вас есть.

Чтобы получить то, что вы хотите, чтобы прочитать путь к вашему приложению, перейдите по пути к классу, откройте банки и зайдите в директории, найдите файлы, которые заканчиваются *.class, и получите их как ресурс, например getResource(full_class_name), или получите его напрямую как класс используя Class.forName().

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

Если это не упражнение, я бы рекомендовал вам использовать Reflections библиотеку, которая делает все, что вам нужно, и (возможно) еще больше ... :)

Некоторые подробности

Java свойство системы «ява .class.path "содержит путь к вашему приложению, разделенный ; на Windows и : на Unix.

Итак, это путь, вы можете получить список элементов пути класса: System.getProperty("java.class.path").split(File.pathSeparator)

Вот некоторые примеры кода, которые могут помочь вам начать:

for (String cpElement : System.getProperty("java.class.path").split(File.pathSeparator)) { 
    File cpFile = new File(cpElement); 
    if (!cpFile.exists()) { 
     continue; 
    } 
    if (cpFile.isDirectory()) { 
     findClassesInDirectory(cpFile); 
    } else { 
     findClassesInArchive(cpFile); 
    } 
} 

Etc и т.д. Я оставляя реализацию findClassesInDirectory() и findClassesInArchive() для вас. Хорошее упражнение. Повеселись.

+0

Не могли бы вы подробнее рассказать об этом - «перебирать путь к классу, открывать банки и входить в каталоги», как я могу это сделать? Спасибо за ваше объяснение тоже, я нашел, что это очень полезно, очень ценится :) – user3373261

+1

@ user3373261, пожалуйста, ознакомьтесь с дополнениями к моему первоначальному ответу. – AlexR

+0

Благодарим вас за расширенный комментарий и пример кода, чтобы помочь мне начать работу! :) – user3373261

0

да, вы можете так это. Но с затмением он больше переносит дерево АСТ, а не отражения. Посмотрите, хотите ли вы перебирать исходный код и посмотреть, какой исходный файл реализует интерфейс, который вам, вероятно, нужен, чтобы это сделать. Но, с другой стороны, если вы хотите интроспектировать во время выполнения файлы классов в данном пакете или в папке, реализующей указанный интерфейс, тогда вам нужны Reflections для этого. В любом случае это выполнимо. Я не могу дать вам код, чтобы попробовать это, так как немного времени с Google даст вам ответы, которые вам нужны, хотя и не все в одном месте.

1

Вы слышали о библиотеках guava для Java. Они предоставляют полезные утилиты для отражения.

Для вашей конкретной проблемы я бы посмотрел TypeToken и метод getTypes().

Успехов

0

Отражение не обеспечивает все операции на общую инспекцию.

Для класса известно можно получить физический адрес класса SomeClass с помощью:

CodeSource codeSource = SomeClass.class.getProtectionDomain().getCodeSource(); 
if (codeSource == null) { 
    // Run-time class; URL into the rt.jar. 
} else { 
    URL url = codeSource.getLocation(); 
    // "file:/.... /classes/.../SomeClass.class" 
    // "jar:file:/... /someJar.jar!/.../SomeClass.class" 
} 

Для Java выполняются классы времени (rt.jar) CodeSource будет нулевым. По URL-адресу банки вы можете открыть (zip) file system и пройти через папки как любую реальную файловую систему.

Возможно, вы захотите проверить классы без $ на имя (встроенные, созданные анонимные классы): только fileName.matches("[^$]+\\.class").

Смежные вопросы