У меня есть устаревший смешанный проект Scala / Java. Он имеет собственный инструмент отображения ORM для домашнего пивоварения, который генерирует несколько классов сущностей Java и затем работает с ними в Scala, отображая их из / в пользовательские карты свойств и файлы yaml.
Сегодня я наткнулся на проблему, заключающуюся в том, что инструмент ORM преобразует все строки внутри List<String>
в карты Array[Byte]
(что приводит к дальнейшему преобразованию данных в java.io.ByteArrayInputStream вместо простого списка строк Scala).
Пытаясь решить проблему и добавить List[String]
к сопоставителю значений поля ORM, я получил бит по типу стирания. К сожалению, у меня нет контроля над классами Java, сгенерированными автоматическим инструментом, поэтому я не могу использовать TypeTags и т.д .; Кажется, отражение - моя единственная надежда.
Вот упрощенный пример проблемного варианта использования.
Java-объекты:
public class SubEntity {
}
import java.util.ArrayList;
import java.util.List;
public class Entity {
protected List<SubEntity> field1;
protected List<String> field2;
public List<SubEntity> getField1() {
if (field1 == null) {
field1 = new ArrayList<SubEntity>();
}
return this.field1;
}
public List<String> getField2() {
if (field2 == null) {
field2 = new ArrayList<String>();
}
return this.field2;
}
}
Часть проблемного кода Scala:
val ent = new Entity
ent.getClass.getMethods
.filter (m => m.getName.startsWith("get") && m.getName != "getClass")
.filter (m => m.getParameterTypes.size == 0)
.foreach (m => m.invoke(ent) match {
case null => null
// Not able to differentiate between List[String] and List[SomeEntity] and Array[Byte[
// at runtime because of type erasure :(
// How to solve this?
case s: java.util.List[java.lang.String] => {
println(s"Found list of strings in ${m.getName}, the values are ${s.toList}")
}
case s: java.util.List[SubEntity] => {
println(s"Found list of SubEntity in ${m.getName}")
}
case _ => println(s"Unknown ${m.getName}")
})
В зависимости от того, какой блок я комментирую, он печатает
Found list of strings
или
Found list of SubEntity
для обоих полей одновременно и не может правильно определить, что getField1
возвращает List[SubEntity]
, а getField2
возвращает List[java.lang.String]
.
Как мне исправить проблему и заставить матч работать по мере необходимости?