Информация об общем типе полей в чертах отсутствует? - PullRequest
0 голосов
/ 07 мая 2011

Я обнаружил эту проблему при использовании 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, поэтому 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<Tag>, но поле tags не является.

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

Ответы [ 2 ]

2 голосов
/ 07 мая 2011

Вот как 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 голос
/ 07 мая 2011

Я не знаю, что еще показать: он не может сказать «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>
...