Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
确定Scala类中选项字段的类型 问题:_Scala_Reflection - Fatal编程技术网

确定Scala类中选项字段的类型 问题:

确定Scala类中选项字段的类型 问题:,scala,reflection,Scala,Reflection,如何确定类中每个字段的类型 鉴于以下案例类别: case class GenericCaseClass( a: Boolean, b: Byte, c: Short, d: Int, e: Long, f: Float, g: Double, h: Char, i: String, j: Option[Boolean], k: Option[Byte], l: Option[Short], m

如何确定类中每个字段的类型

鉴于以下案例类别:

case class GenericCaseClass(
    a: Boolean,
    b: Byte,
    c: Short,
    d: Int,
    e: Long,
    f: Float,
    g: Double,
    h: Char,
    i: String,
    j: Option[Boolean],
    k: Option[Byte],
    l: Option[Short],
    m: Option[Int],
    n: Option[Long],
    o: Option[Float],
    p: Option[Double],
    q: Option[Char],
    r: Option[String]
)
初步尝试 初步结果
  • 布尔值
  • 字节
  • Int
  • 长的
  • 浮动
  • 双重的
  • 煤焦
  • 选项[布尔值]
  • 选项[布尔值]
  • 选项[布尔值]
  • 选项[布尔值]
  • 选项[布尔值]
  • 选项[布尔值]
  • 选项[布尔值]
  • 选项[布尔值]
  • 选项[布尔值]
当前尝试 为了获取选项的内部类型,我在if语句链的开头添加了以下内容:

if (scalaClass == classOf[Option[_]]) {
    val innerType = field
        .getGenericType
        .asInstanceOf[ParameterizedType]
        .getActualTypeArguments
        .head
        .getTypeName

    println("Option[_] -> " + innerType)
}
但它似乎只适用于字符串:

  • 布尔值
  • 字节
  • Int
  • 长的
  • 浮动
  • 双重的
  • 煤焦
  • 选项[\u]->java.lang.Object
  • 选项[\u]->java.lang.Object
  • 选项[\u]->java.lang.Object
  • 选项[\u]->java.lang.Object
  • 选项[\u]->java.lang.Object
  • 选项[\u]->java.lang.Object
  • 选项[\u]->java.lang.Object
  • 选项[\u]->java.lang.Object
  • 选项[\]>java.lang.String

注意:我使用的是Scala版本2.11.11。

使用Java反射很快让我头疼,所以这里有一个非常简单的Scala解决方案:

import scala.reflect.runtime.universe._

//--Your case class definition--//

val values = typeOf[GenericCaseClass].members.filterNot(_.isMethod)

def prettyPrintField(symbol: Symbol): Unit = {
  val name = symbol.name
  val typeSignature: Type = symbol.typeSignature
  println(s"$name: $typeSignature")
}

values.foreach(prettyPrintField)
输出:

r : Option[String]
q : Option[Char]
<- rest of fields ->
a : Boolean
r:Option[String]
q:选项[Char]
a:布尔型

使用
ClassTag
访问运行时类型信息:

import scala.reflect.ClassTag
def getOptionType[T](opt: Option[T])(implicit t: ClassTag[T]) = t.runtimeClass

您正在使用JVM运行时反射来反映静态Scala类型。这不可能奏效。a) JVM和Scala是两个完全不同的东西,JVM对Scala一无所知。(在这种特殊情况下:JVM没有泛型,但您正在尝试对泛型类型进行反射。)b)运行时反射不一定能告诉您静态类型。(在这种特殊情况下:Scala执行泛型类型擦除,即泛型类型在编译时被擦除,在运行时不存在,
Option[Foo]
Option[Bar]
)之间没有区别。@JörgWMittag你可以得到Scala类型,我的解决方案基于这个答案。在Java中可以这样做吗?我需要它来制作Swagger-core.modelsolver。
import scala.reflect.ClassTag
def getOptionType[T](opt: Option[T])(implicit t: ClassTag[T]) = t.runtimeClass