Перебор каждого класса в пакете в Scala

#scala

#scala

Вопрос:

Есть ли способ, которым я могу «перебирать» набор классов в указанном пакете в Scala?

Примером использования является управление набором сервисов, наследуемых от признака BaseService, которые становятся доступными через предоставленное имя REST API. Класс Manager должен иметь возможность предоставлять список служб, а также проверять, существует ли предоставленная служба, и, если да, создавать ее экземпляр для выполнения перегруженной функции.

Моя мысль заключается в чем-то вроде этого псевдокода:

 for ( clazz <- com.demo.pkg ) {
    val service = Class.forName(clazz).newInstance
    registerService( service )
}
  

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

В Python это тривиально из-за dir(), а в PHP довольно просто из-за функций classloader, но я новичок в Scala.

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

Обновить:

Я принял ответ JPP ниже, но он прав, это слишком дорогой процесс для обычной операции. Итак, мне нужно изменить свой подход. Класс manager вместо этого будет поддерживать статический список классов служб. Хотя это и не идеально с точки зрения разработки, прирост скорости выполнения, похоже, того стоит.

Ответ №1:

В настоящее время (2.8.1 / 2.9) в Scala нет специальной системы отражения / самоанализа, но вы можете свободно использовать Java. В этом конкретном случае вы можете перенести один из методов, используемых на стороне Java, для перечисления всех классов в пакете, например, как показано здесь (обязательно укажите версию в комментариях):

http://snippets.dzone.com/posts/show/4831

На самом деле этот метод не использует отражение Java для поиска информации о классах; вместо этого он в основном просматривает все ресурсы, доступные загрузчику классов, и проверяет, какие из них являются .class файлами.

Однако я вижу несколько предостережений:

  • Как и в Java, вы можете видеть классы, видимые только определенному загрузчику классов (это может быть проблемой, например, в приложениях OSGi)
  • Эта операция достаточно дорогостоящая в Java, и тем более в Scala, поскольку scalac генерирует множество дополнительных классов для всех анонимных функций, сгенерированных в вашем коде, которых может быть значительное количество благодаря таким методам, как filter, map, flatMap и т.д. Вы можете попытаться отфильтровать их на основе их имени.

Комментарии:

1. На данный момент, да. Знаете ли вы способ сделать это с помощью отражения Scala? Не стесняйтесь добавлять ответ. Кажется трудным представить, что существует принципиально другой способ, поскольку ничто в JVM не говорит вам о том, что какой-то jar, о котором вы не знаете, не добавит больше классов в данный пакет просто потому, что он находится в пути к классам среды выполнения.

2. ссылка на фрагменты не работает