繁体   English   中英

Scala 反射以获取对象的所有字段的类型

[英]Scala Reflection to get the types of all fields of an object

我需要创建一个接受同一类的两个对象的函数。 一个是更新的对象,另一个是旧的对象。 我需要通过考虑旧对象来找到更新对象的差异。 就像我们在 java 中有 getDeclaredFields 方法来获取所有变量一样。我正在寻找一种方法来获取对象的所有字段,然后我必须一个一个地迭代字段,并根据它的类型我必须检查等于两个对象。

// 注释中的代码包括:

def trackChanges(newRecord:Object,oldRecord:Object) :String = { 
  val fields :Array[Field] = newRecord.getClass.getDeclaredFields 
  var check : String = "Equal" 
  for( i <- 0 to fields.length-1) { 
    fields(i).setAccessible(true) 
    val fieldType:Object = fields(i).getType 
    fieldType match { 
      case x: String => fields(i).get(newRecord).equals(fields(i).get(oldRecord)) 
      case x: java.lang.Double => println("String") 
      case x: Seq[] => println("String") 
      case x: List[] => }

所以你有一些对象:

scala> trait MyTrait {
     | val x: String
     | val y: Int
     | }
defined trait MyTrait

scala> object MyObjectA extends MyTrait {
     | val x = "priyam"
     | val y = 1
     | }
defined object MyObjectA

scala> object MyObjectB extends MyTrait {
     | val x = "singh"
     | val y = 2
     | }
defined object MyObjectB

scala> object MyObjectC extends MyTrait {
     | val x = "priyam"
     | val y = 1
     | }
defined object MyObjectC

由于您无法比较两个对象,因此您可以从您的对象创建一个case class 那将免费为您提供一个比较器:

scala> def createFromObject(obj: MyTrait): MyCaseClass = MyCaseClass(obj.x, obj.y)
createFromObject: (obj: MyTrait)MyCaseClass

现在,您比较对象:

scala> createFromObject(MyObjectA) == createFromObject(MyObjectC)
res5: Boolean = true

scala> createFromObject(MyObjectA) == createFromObject(MyObjectB)
res6: Boolean = false

您还可以从原始对象或案例类中调用单个成员:

scala> MyObjectA.x
res7: String = priyam

scala> createFromObject(MyObjectA).a
res8: String = priyam

想法 1. 不要在运行时使用反射。 反射是一种繁重而缓慢的机制,因此使用它来跟踪对象的变化可能会扼杀解决方案的所有性能。 我建议您直接为每个字段手动编写它。 它会很快。

if (obj1.field != obj2.field) {}

想法 2. 但我假设你是说你自己是一个优秀的程序员,你担心未来的代码维护,我假设你懒得手工编写。 所以。 因为 scala 在 JVM 上运行,所以这里也可以使用 java-reflection。 您可以自由使用 getDeclaredFields。 如果你想使用 scala 反射,你可以在这里看到: https : //github.com/yudnikov/transactions/blob/master/src/main/scala/ru/yudnikov/meta/describing/Reflector.scala - 这里是例子scala 反射用法。 注意

def getTerms(...)

你需要了解什么是运行时镜像......

想法 3. 对于这个问题,真正的程序员解决方案是在编译时使用带有反射的 Scala 宏,在编译期间自动从 Idea №1 生成低级轻量级代码。 但我帮不了你。 祝你好运 ;)

def trackChanges(newRecord:Object,oldRecord:Object) :String = {
    val fields :Array[Field] = newRecord.getClass.getDeclaredFields
     var check : String = "Equal"
   for( i <- 0 to fields.length-1)
   {
     fields(i).setAccessible(true)
    val fieldType:Object= fields(i).getType
    fieldType match
        {
          case x: String=> fields(i).get(newRecord).equals(fields(i).get(oldRecord))
          case x: java.lang.Double => println("String")
          case x: Seq[_] => println("String")
          case x: List[_] =>
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM