如何仅使用零参数构造函数通过Java反射创建上下文绑定的Scala类的新实例?
我正在用Scala编写客户端代码,它需要与Java框架接口。该框架负责创建通过API指定的类的对象实例,它使用反射来实现。例如:如何仅使用零参数构造函数通过Java反射创建上下文绑定的Scala类的新实例?,java,scala,reflection,Java,Scala,Reflection,我正在用Scala编写客户端代码,它需要与Java框架接口。该框架负责创建通过API指定的类的对象实例,它使用反射来实现。例如: 公共类ReflectionUtil{ 公共静态T newInstance(类aClass){ T结果; 试一试{ 构造函数meth=aClass.getDeclaredConstructor(新类[]{}); 方法设置可访问(真); 结果=meth.newInstance(); }捕获(例外e){ 抛出新的运行时异常(e); } 返回结果; } } 我要创建的对象实
公共类ReflectionUtil{
公共静态T newInstance(类aClass){
T结果;
试一试{
构造函数meth=aClass.getDeclaredConstructor(新类[]{});
方法设置可访问(真);
结果=meth.newInstance();
}捕获(例外e){
抛出新的运行时异常(e);
}
返回结果;
}
}
我要创建的对象实例的类是在Scala中实现的,并在具有上下文绑定的类型上进行参数化。例如:
类OrderedValue[A](变量值:A)(隐式ord:Ordering[A]){
def get:A=值
定义集(x:A)={value=x}
def cmp(that:OrderedValue[A]):Int=ord.compare(this.value,that.value)
}
当我将这个类传递给Java框架来构造新实例时,我遇到了一个问题,因为框架假设该类将有一个可用的零参数构造函数。例如,以下代码将导致newInstance
中的NoSuchMethodException
:
def main(参数:数组[字符串]){
val a:OrderedValue[Int]=ReflectionUtil.newInstance(classOf[OrderedValue[Int]]
val b:OrderedValue[Int]=ReflectionUtil.newInstance(classOf[OrderedValue[Int]])
a、 第(3)组
b、 一套(5)
println(a.cmp(b))
}
解决此问题的一种尝试是向OrderedValue
添加零参数构造函数,但是隐式参数ord
没有合理的值。将其设置为null
将导致cmp
内出现NullPointerException
:
def this()=this(null.asInstanceOf[A])(null.asInstanceOf[Ordering[A]]
另一种方法是对OrderedValue
的特定具体值进行子类化。例如:
类OrderedIntValue(val v:Int)扩展了OrderedValue[Int](v){
def this()=this(null.asInstanceOf[Int])
}
val a:OrderedValue[Int]=ReflectionUtil.newInstance(classOf[OrderedValue[Int]]
这将起作用,但并不理想,因为了解OrderedValue
的具体类型并不总是方便或可能的。例如,newInstance
可以在一个范围内调用,该范围也在一个类型上参数化(即,我们不知道它具体是一个Int
)
因此,我的问题是:鉴于上下文边界(即类型类)是Scala中非常有用且现在常用的功能,并且鉴于我无法更改与之交互的Java框架的内部结构,是否有人遇到或开发了一种方法,可以使这一切正常工作?隐式参数由Scala编译器在编译时填写。如果要使用反射实例化类,则必须手动指定这些参数。这是没有办法的。因此,您可以使用上下文边界,也可以不使用参数构造函数。我发现从Java调用Scala代码的最简单方法是使用相当于POJO的Scala编写一个中间Scala层。没有隐式、签名中没有闭包、没有伴随对象、没有复杂的类型推断等等(当然,您可以在内部使用这些)。我还尝试用java.util集合替换签名中的大多数scala集合类型 是的,它丑陋、乏味而且不太灵活,但至少它消除了Java方面的许多语法噩梦