2013-05-13 5 views
4

Мне нужно получить все интерфейсы во время выполнения от данного класса (все загружаются в ClassLoader).Scala: получить интерфейсы mixin во время выполнения

Например, если класс объявлен следующим образом:

trait B 
trait C 
trait D  
class A extends B with C with D 

Я хочу, чтобы получить эту информацию во время выполнения: А зависит от В и С и D. java getInterfaces() (или интерфейсы() из библиотеки clapper) дает только первую зависимость, а именно: A зависит от B.

Есть ли способ достичь этого?

Наверное, отражением, но я не знаю, как?

+0

Проблема заключается в том, что я не знаю, класс * априори *. Поэтому я не могу позвонить typeOf [A] Что я получаю, это список классов, созданных путем чтения целевых/классов и их интенсификации с помощью Class.forName, так что я получаю список неизвестных классов во время выполнения. val classes: List [Class [_] = ... // мой список классов чтения classes.map {c => c-> ???} // Карта с ее интерфейсами – Mathieu

ответ

2

This question дает ответ:

import scala.reflect.runtime.universe._ 

trait B 
trait C 
class A extends B with C 

val tpe = typeOf[A] 
tpe.baseClasses foreach {s => println(s.fullName)} 
    // A, C, B, java.lang.Object, scala.Any 


Он работает в REPL, но когда я поставил код в файл сценария Scala и казнили его, он не сделал больше:

typeOf[A] 
    // Compiler error: No TypeTag available for this.A 

weakTypeTag Использование вместо не помогло

weakTypeTag[A] 
    // Runtime error: scala.reflect.internal.FatalError: 
    // ThisType(free type $anon) for sym which is not a class 

У меня такое же поведение с Scala 2.10.0, 2.10.1 и 2.11.0-M2.

+0

Спасибо за анкетирование. – Mathieu

+0

Возможно, вам не хватает зависимости _scala-reflect_ ('libraryDependencies + =" org.scala-lang "%" scala-reflect "%" 2.10.0 "'), которая предоставляется в REPL. – jeslg

+0

Спасибо за предложение. Я явно добавил его в путь к классам, который 'scala.bat' автоматически делает в любом случае, если я не ошибаюсь, но ничего не изменилось. Более того, я предполагаю, что 'import scala.reflect.runtime.universe._' (ранее был пропущен импорт из моего ответа) потерпел бы неудачу, если бы библиотека уже не присутствовала. –

2

Решение, которое я нашел с отражением:

import scala.reflect.runtime.{universe => ru} 
val mirror = ru.rootMirror 
val t = m.staticClass(classString).typeSignature 
t.baseClasses