Reputation: 298898
I have a use case where I need to do some Java reflection on some Scala objects (don't even ask). Anyway, I sometimes need to add these objects to an annotation, in Scala.
Here's my (java) annotation:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
Class<?>[] value();
}
And let's say this is my Scala object:
object Foo{}
In Java, I can reference Foo using my above annotation like this:
@MyAnnotation(Foo.class)
class SomeClass{}
In Scala, however, I don't see how I can get a type literal from an Object:
@MyAnnotation(Array(classOf[Foo]))
class SomeClass{}
This fails, with error message:
not found: type Foo
Is there any way I can reference my Foo object type in a Java annotation? Note that I can't use Foo.getClass
, because that's a method call, not a constant.
Upvotes: 1
Views: 313
Reputation: 51658
Try
@MyAnnotation(Array(classOf[Foo.type]))
class SomeClass
classOf[Foo.type]
is allowed since Scala 2.13.4
https://github.com/scala/scala/pull/9279
https://github.com/scala/bug/issues/2453
In older Scala you can create a class literal manually using a whitebox macro
def moduleClassOf[T <: Singleton]: Class[T] = macro impl[T]
def impl[T: c.WeakTypeTag](c: whitebox.Context): c.Tree = {
import c.universe._
Literal(Constant(weakTypeOf[T]))
}
Usage:
@MyAnnotation(Array(moduleClassOf[Foo.type]))
class SomeClass
https://gist.github.com/DmytroMitin/e87ac170d107093a9b9faf2fd4046bd5
Upvotes: 2