【问题标题】:Get class of Scala object for annotation获取用于注释的 Scala 对象类
【发布时间】:2021-10-25 01:43:10
【问题描述】:

我有一个用例,我需要对一些 Scala 对象进行一些 Java 反射(甚至不要问)。无论如何,我有时需要在 Scala 中将这些对象添加到注释中。

这是我的 (java) 注释:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
   Class<?>[] value();
}

假设这是我的 Scala 对象:

object Foo{}

在 Java 中,我可以像这样使用上面的注释来引用 Foo:

@MyAnnotation(Foo.class)
class SomeClass{}

然而,在 Scala 中,我看不到如何从 Object 中获取类型文字:

@MyAnnotation(Array(classOf[Foo]))
class SomeClass{}

此操作失败,并显示错误消息:

未找到:键入 Foo

有什么方法可以在 Java 注释中引用我的 Foo 对象类型?请注意,我不能use Foo.getClass,因为那是一个方法调用,而不是一个常量。

【问题讨论】:

  • 试试@MyAnnotation(Array(Foo.getClass)) class SomeClass。有用吗?
  • @DmytroMitin annotation argument needs to be a constant; found: Foo.getClass()
  • 嗯...重新打开。 (为了记录,链接是stackoverflow.com/questions/9635563/…

标签: java scala reflection annotations


【解决方案1】:

试试

@MyAnnotation(Array(classOf[Foo.type]))
class SomeClass

classOf[Foo.type] 自 Scala 2.13.4 起允许使用

https://github.com/scala/scala/pull/9279

https://github.com/scala/bug/issues/2453


在旧版 Scala 中,您可以使用 whitebox

手动创建类文字
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]))
}

用法:

@MyAnnotation(Array(moduleClassOf[Foo.type]))
class SomeClass

https://gist.github.com/DmytroMitin/e87ac170d107093a9b9faf2fd4046bd5

【讨论】:

  • 这给出了一个新错误:class type required but com.myapp.Foo.type found
  • @SeanPatrickFloyd 你的 Scala 版本是什么?
  • 啊废话,我的 scala 太旧了 (2.12.14)
  • @SeanPatrickFloyd 你能升级到 Scala ≥2.13.4 吗?
  • 我怀疑在升级到 2.13.x 之前我会真正使用它,因为我的公司不赞成宏,但这绝对是正确的答案,谢谢
猜你喜欢
  • 2022-09-30
  • 2020-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-18
  • 2017-09-21
  • 2021-11-01
相关资源
最近更新 更多