特征中字段的通用类型信息丢失?

发布于 2024-11-05 10:56:58 字数 1770 浏览 0 评论 0原文

我在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,但是标签 没有。

而接口HasTags为:

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

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

我们可以看到,方法tags()的返回值为List,但是字段>标签 不是。

由于吗啡是通过字段来获取信息的,所以它无法正常工作。

I found this problem when I use Morphia in scala. It checks the fields of a class by reflection, and get necessary type information for mapping.

But if I use traits, and define some collection fields, the generic type information will be lost, which cause Morphia can't get enough information, and throw exceptions.

See my code:

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 {

}

I compiled the scala file, and get some java class files. Then I use java decompiler to see the content of the java byte codes:

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

You can see there is no Tag here, so Morphia will fail.

I used scala 2.8.1. Is there any way to fix it?


UPDATE

@extempore said, maybe javap doesn't display that Tag information.

But I used a program called Java Decompiler, not javap.

I tried this code:

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

And see the byte code in Java Decompiler, it displays:

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

We can see the tags2 contains Tag, but tags doesn't.

And the interface HasTags is:

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

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

We can see, the return value of method tags() is List<Tag>, but the field tags is not.

Since morphia get the information by fields, it can't work correctly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

只是我以为 2024-11-12 10:56:58

这就是 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;>;;

That's how javap displays things. It doesn't mean the signature isn't present.

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

That's how you know it is. You can also see it in the constant pool.

const #3 = Asciz    tags;
const #4 = Asciz    ()Ljava/util/List;;
const #5 = Asciz    ()Ljava/util/List<LTag;>;;
傾城如夢未必闌珊 2024-11-12 10:56:58

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

% 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>

I don't know what else to show: it can't say "Tag" in this output unless the signature is present. Field and method.

% 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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文