Ben*_*ver 4 java reflection scala
我在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;
}
}
Run Code Online (Sandbox Code Playgroud)
我想要创建的对象实例的类在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)
}
Run Code Online (Sandbox Code Playgroud)
当我将此类传递给Java框架以构造新实例时,我遇到了一个问题,因为框架假设该类将具有零参数构造函数.例如,以下代码将导致NoSuchMethodExceptionfrom 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))
}
Run Code Online (Sandbox Code Playgroud)
尝试解决此问题的方法是添加零参数构造函数,OrderedValue但隐式参数没有合理的值ord.将其设置为null将导致NullPointerException内部cmp:
def this() = this(null.asInstanceOf[A])(null.asInstanceOf[Ordering[A]])
Run Code Online (Sandbox Code Playgroud)
另一种方法是子类化特定的具体值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]])
Run Code Online (Sandbox Code Playgroud)
这将起作用,但并不理想,因为了解具体类型并不总是方便或可能OrderedValue.例如,newInstance可以在也在类型上参数化的范围内调用(即,我们不知道它是特定的Int).
所以我的问题是:鉴于上下文边界(即类型类)是Scala中非常有用且现在常用的特性,并且考虑到我无法更改我正在连接的Java框架的内部,有人遇到过或者开发出一种方法,可以使这一切工作?
| 归档时间: |
|
| 查看次数: |
1583 次 |
| 最近记录: |