我在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
没有。{/ p>
接口HasTags
是:
public abstract interface HasTags extends ScalaObject
{
public abstract List<Tag> tags();
@TraitSetter
public abstract void tags_$eq(List<Tag> paramList);
}
我们可以看到,方法tags()
的返回值为List<Tag>
,但字段tags
不是。
由于morphia按字段获取信息,因此无法正常工作。
答案 0 :(得分:2)
这就是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;>;;
答案 1 :(得分:1)
我不知道还有什么要显示:除非签名存在,否则不能在此输出中说“Tag”。领域和方法。
% 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>