【问题标题】:Any way to obtain a Java class from a Scala (2.10) type tag or symbol?有什么方法可以从 Scala (2.10) 类型标记或符号中获取 Java 类?
【发布时间】:2012-10-15 18:33:09
【问题描述】:

看起来这让我很接近,但是 (a) 不完全是(见下文),并且 (b) 使用名称的字符串表示感觉就像是 hack...

scala> import scala.reflect.runtime.universe._import scala.reflect.runtime.universe._

scala> val t = typeOf[Int]
t: reflect.runtime.universe.Type = Int

scala> t.typeSymbol.asClass.fullName
res0: String = scala.Int

scala> object X { class Y } 
defined module X

scala> val y = typeOf[X.Y]
y: reflect.runtime.universe.Type = X.Y

scala> Class.forName(y.typeSymbol.asClass.fullName)
java.lang.ClassNotFoundException: X.Y [...]

我是否缺少一些更直接的方法来访问这些信息?还是最好,如果我在某个时候还需要类信息,只是为了保留一组并行的 Java 类信息? (呃!)

【问题讨论】:

  • 如果你能得到一个 AnyRef 类型的实例,你就不能恢复到 java.lang.Object-y 的优点,然后调用 myObj.getClass().getName() 吗?
  • 例如,对象 X { class Y } 定义模块 X scala> (new X.Y).getClass.getName res7: java.lang.String = X$Y
  • 作为一个快速建议,尝试运行scala -Xprint:typer 以查看 REPL 是否以及如何实际将 X 包装到它自己的对象中。
  • 我一直在尝试让Class.forName(package.and.object) 在 REPL 中工作,但未能成功。

标签: scala reflection scala-2.10


【解决方案1】:

接收java.lang.Class 或使用反射实例化对象必须使用镜像而不是类型和符号来完成,这些是 Scala 的编译时间信息:

scala> val m = runtimeMirror(getClass.getClassLoader)
m: reflect.runtime.universe.Mirror = JavaMirror with ...

scala> m.runtimeClass(typeOf[X.Y].typeSymbol.asClass)
res25: Class[_] = class X$Y

【讨论】:

  • 他只说“类信息”,没有提到实例化。但是,这也许是他的用例......
  • 这似乎可以做到,只要你碰巧选择了正确的类加载器。
  • ClassMirror.runtimeClass 功能已从 RC1 中删除,因为有一个更短的替代方案:只需 m.runtimeClass(typeOf[X.Y].typeSymbol.asClass)
【解决方案2】:

假设tag是你要获取java类的类的类型标签,你可以说:

val mirror = tag.mirror
val clazz = mirror.runtimeClass(tag.tpe.typeSymbol.asClass)

与 sschaef 的回答基本相同,只是您应该直接从标签中使用镜像,而不是使用当前类的类加载器的镜像。如果当前类和你有标签的其他类使用不同的类加载器,在这种情况下你会遇到类加载错误,但按照我解释的方式没有错误。

clazz 变量将保存您想要获取的任何 java 类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    相关资源
    最近更新 更多