Я пишу клиентский код в Scala, который должен взаимодействовать с фреймворком на Java.Фреймворк отвечает за создание экземпляров объектов классов, указанных через API, что он делает с помощью отражения.Например:
public class ReflectionUtil {
public static <T> T newInstance(Class<T> aClass) {
T result;
try {
Constructor<T> meth = aClass.getDeclaredConstructor(new Class[]{});
meth.setAccessible(true);
result = meth.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
return result;
}
}
Классы экземпляров объектов, которые я хочу создать, реализованы в Scala и имеют параметризацию для типа, к которому привязан контекст.Например:
class OrderedValue[A](var value: A)(implicit ord: Ordering[A]) {
def get: A = value
def set(x: A) = { value = x }
def cmp(that: OrderedValue[A]): Int = ord.compare(this.value, that.value)
}
Я сталкиваюсь с проблемой, когда передаю этот класс в среду Java для создания новых экземпляров, поскольку среда предполагает, что класс будет иметь конструктор с нулевым аргументом.Например, следующий код приведет к NoSuchMethodException
из newInstance
:
def main(args: Array[String]) {
val a: OrderedValue[Int] = ReflectionUtil.newInstance(classOf[OrderedValue[Int]])
val b: OrderedValue[Int] = ReflectionUtil.newInstance(classOf[OrderedValue[Int]])
a.set(3)
b.set(5)
println(a.cmp(b))
}
Попытка решить эту проблему - добавить конструктор с нулевым аргументом в OrderedValue
, однако нетразумное значение для неявного параметра ord
.Установка null
приведет к NullPointerException
в cmp
:
def this() = this(null.asInstanceOf[A])(null.asInstanceOf[Ordering[A]])
Другой подход заключается в создании подкласса конкретного конкретного значения OrderedValue
.Например:
class OrderedIntValue(val v: Int) extends OrderedValue[Int](v) {
def this() = this(null.asInstanceOf[Int])
}
val a: OrderedValue[Int] = ReflectionUtil.newInstance(classOf[OrderedValue[Int]])
Это будет работать, но не идеально, так как не всегда удобно или возможно узнать конкретный тип OrderedValue
.Например, newInstance
может вызываться в области видимости, которая также параметризована для типа (т. Е. Мы не знаем, что это конкретно Int
).
Поэтому мой вопрос: учитывая границы этого контекста(т. е. классы типов) являются очень полезной и в настоящее время широко используемой функцией в Scala, и, учитывая, что я не могу изменить внутреннюю среду Java-фреймворка, с которым я взаимодействую, сталкивался ли кто-либо с разработанным подходом, который может заставить все это работать