scala类对象null值检测并填充

scala类对象null值检测并填充

  • 这段代码是一个名为 checkAndFillNull 的 Scala 函数,它接受一个类型为 T 的对象作为输入,并返回相同类型的对象。该函数检查输入对象中的任何字段是否为 null,如果是,则根据其类型使用默认值填充它们
  • 例如,如果字段的类型为 Int,则会用 0 填充。如果字段的类型为 String,则会用空字符串(“”)填充。如果字段的类型为 Option[_],则会用 None 填充。如果字段的类型未在函数中指定,则会用 null 填充。

1. 函数实现


  
  import scala.reflect.ClassTag
  import scala.reflect.runtime.universe._

  def checkAndFillNull[T: TypeTag : ClassTag](obj: T): T = {
    // 获取输入对象的运行时的镜像
    val mirror = runtimeMirror((obj.getClass.getClassLoader))
    // 获取类符号
    val classSymbol = typeOf[T].typeSymbol.asClass
     // 获取类镜像
    val classMirror = mirror.reflectClass(classSymbol)
    // 获取构造函数符号
    val constuctorSymbol = typeOf[T].decl(termNames.CONSTRUCTOR).asMethod
    // 获取构造函数符号并反射构造函数镜像
    val constructorMirror = classMirror.reflectConstructor(constuctorSymbol)
    // 遍历构造函数符号的参数列表
    val args = constuctorSymbol.paramLists.flatten.map {
          // 对于每个参数
      param =>
//        获取参数名称
        val paramName = param.name.toString
//        获取getter方法符号
        val getterMethodSymbol = typeOf[T].decl(TermName(paramName)).asMethod
        // 反射getter方法镜像
        val getterMethodMirror = mirror.reflect(obj).reflectMethod(getterMethodSymbol)
        // 使用getter方法镜像获取字段值
        val value = getterMethodMirror.apply()
        // 如果字段值位null, 则根据字段类型使用匹配表达式确定默认值
        if (value == null) {
          val default = param.typeSignature match {
            case t if t =:= typeOf[Boolean] => false
            case t if t =:= typeOf[Char] => '\u0000'
            case t if t =:= typeOf[Byte] => 0.toByte
            case t if t =:= typeOf[Short] => 0.toShort
            case t if t =:= typeOf[Int] => 0
            case t if t =:= typeOf[Long] => 0L
            case t if t =:= typeOf[Double] => 0.0
            case t if t =:= typeOf[Float] => 0.0f
            case t if t <:< typeOf[String] => "default"
            case t if t <:< typeOf[Option[_]] => None
            case _ => None
          }
          // 将默认值转换为Object类型,添加到参数列表中
          default.asInstanceOf[Object]
        } else {
          value.asInstanceOf[Object]
        }

    }
    // 使用构造函数镜像和参数列表创建新对象并返回
    constructorMirror(args: _*).asInstanceOf[T]
  }

2. 测试用例


val testObj = TestClass(1, null, null, true, 'a', 1, 1, 1L, 1.0, 1.0f)
print(result)
assert(result.a == 1)
assert(result.b == "default")
assert(result.c == None)
assert(result.d == true)
assert(result.e == 'a')
assert(result.f == 1)
assert(result.g == 1)
assert(result.h == 1L)
assert(result.i == 1.0)
assert(result.j == 1.0f)



3. 输出效果

在这里插入图片描述