Информация об общем типе полей в свойствах отсутствует?

Я обнаружил эту проблему, когда использую Morphia в scala. Он проверяет поля класса путем отражения и получает необходимую информацию о типе для сопоставления.

Но если я использую 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, так что Морфия потерпит неудачу.

Я использовал 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<Tag>, а поле tags — нет.

Поскольку morphia получает информацию по полям, она не может работать корректно.


person Freewind    schedule 07.05.2011    source источник


Ответы (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;>;;
person psp    schedule 07.05.2011

Я не знаю, что еще показать: он не может сказать «Тег» в этом выводе, если нет подписи. Поле и метод.

% 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>
person psp    schedule 07.05.2011