【问题标题】:How to obtain java.lang.reflect.Type from a Scala type?如何从 Scala 类型中获取 java.lang.reflect.Type?
【发布时间】:2020-02-24 06:38:15
【问题描述】:

假设我有一个方法:

def foo(t: java.lang.reflect.Type) = ???

我想打电话给(Int, Int)

这样的调用看起来如何?我试过了:

foo(typeOf[(Int, Int)])

但它似乎不起作用,因为它返回 scala.reflect.runtime.universe.Type 而不是 java.lang.reflect.Type

【问题讨论】:

    标签: scala


    【解决方案1】:

    你应该使用PredefclassOf方法(默认导入):

    "".getClass
    // Class[_ <: String] = class java.lang.String
    
    classOf[String]
    // Class[String] = class java.lang.String
    

    请注意,您不应该自己创建像foo 这样的方法,即使您想调用接受java.lang.reflect.Typejava 方法。你可以使用ClassTag:

    import reflect.{ClassTag, classTag}
    
    def javaFoo(t: java.lang.reflect.Type) = t.toString
    def foo[T: ClassTag]() = javaFoo(classTag[T].runtimeClass)
    
    foo[String]
    // String = class java.lang.String
    

    正如您在调用端看到的,您不需要像 classOftypeOf 这样的辅助函数。

    类型擦除

    正如@cmbaxter 所说:由于类型擦除,您无法为Tuple2[Int, Int] 获取Type - Type 不包含有关类型参数的信息。你会得到Type for Tuple2

    classOf[(Int, Int)] == classOf[(String, String)]
    // Boolean = true
    
    classOf[(Int, Int)] == classOf[(_, _)]
    // Boolean = true
    

    【讨论】:

    • 我在这里同意@senia。 Classjava.lang.reflect.Type 的一个实例,因此它将编译并运行。但请记住,如果您按原样使用它,并传入带有泛型的类型(例如您的示例 Tuple2[Int,Int],则由于擦除,您将无法派生泛型类型。
    【解决方案2】:
    def tagToType[T](implicit tag: scala.reflect.runtime.universe.TypeTag[T]): java.lang.reflect.Type = tag.mirror.runtimeClass(tag.tpe)
    
    def tagToType2[T](implicit tag: scala.reflect.ClassTag[T]): java.lang.reflect.Type = scala.reflect.classTag[T].runtimeClass
    
    tagToType[Array[Int]]
    // class [I
    
    tagToType[(Int, Int)]
    // class scala.Tuple2
    

    您可以将 tag.mirror.runtimeClass(tag.tpe) 转换为 Class[_] 或 Class[T]。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-14
      • 2023-03-13
      • 2021-10-15
      • 2015-05-27
      相关资源
      最近更新 更多