【问题标题】:The generic type information of fields in traits are missing?缺少特征中字段的通用类型信息?
【发布时间】:2011-05-07 08:17:28
【问题描述】:

我在 scala 中使用 Morphia 时发现了这个问题。它通过反射检查类的字段,并获取映射所需的类型信息。

但是如果我使用traits,并定义一些集合字段,泛型类型信息会丢失,导致Morphia无法获取足够的信息,并抛出异常。

查看我的代码:

trait HasTags {
    @Reference
    var tags: java.util.List[Tag] = new java.util.ArrayList[Tag]()  // the generic type is Tag
}

class Question extends Entity with HasTags {

}

我编译了scala文件,得到了一些java类文件。然后我用java反编译器查看java字节码的内容:

public class Question extends Entity implements HasTags {
      @Reference
      private java.util.List tags;
}

你可以看到这里没有Tag,所以Morphia会失败。

我使用了scala 2.8.1。有什么办法可以解决吗?


更新

@extempore 说,也许javap 没有显示Tag 信息。

但我使用了一个名为 Java Decompiler 的程序,而不是 javap。

我试过这段代码:

class Question extends Entity with HasTags {
    @Reference
    var tags2: java.util.List[Tag] = new java.util.ArrayList()
}

并查看Java Decompiler中的字节码,它显示:

public class Question extends Entity implements HasTags {
      @Reference
      private java.util.List tags;
      @Reference
      private java.util.List<models.Tag> tags2;
}

我们可以看到tags2 包含Tag,但tags 没有。

而接口HasTags是:

public abstract interface HasTags extends ScalaObject
{
  public abstract List<Tag> tags();

  @TraitSetter
  public abstract void tags_$eq(List<Tag> paramList);
}

我们可以看到,方法tags()的返回值是List&lt;Tag&gt;,但是字段tags不是。

由于morphia是按字段获取信息的,所以不能正常工作。

【问题讨论】:

    标签: generics scala morphia traits


    【解决方案1】:

    这就是 javap 显示事物的方式。这并不意味着签名不存在。

    scala> classOf[HasTags].getMethod("tags").getGenericReturnType
    res0: java.lang.reflect.Type = java.util.List<Tag>
    

    这就是你所知道的。在常量池中也可以看到。

    const #3 = Asciz    tags;
    const #4 = Asciz    ()Ljava/util/List;;
    const #5 = Asciz    ()Ljava/util/List<LTag;>;;
    

    【讨论】:

      【解决方案2】:

      我不知道还要显示什么:除非存在签名,否则它不能在此输出中显示“标签”。领域和方法。

      % cat a.scala 
      class Tag
      class Ref {
        var tags: java.util.List[Tag] = new java.util.ArrayList()
      }
      % scalac281 a.scala 
      % scala281
      Welcome to Scala version 2.8.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_22).
      Type in expressions to have them evaluated.
      Type :help for more information.
      
      scala> classOf[Ref].getDeclaredField("tags").getGenericType 
      res0: java.lang.reflect.Type = java.util.List<Tag>
      
      scala> classOf[Ref].getMethod("tags").getGenericReturnType 
      res1: java.lang.reflect.Type = java.util.List<Tag>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-12-29
        • 1970-01-01
        • 2015-03-30
        • 2020-09-21
        • 1970-01-01
        • 2015-06-30
        • 1970-01-01
        相关资源
        最近更新 更多