I am writing client code in Scala that should interact with the framework in Java. The structure is responsible for instantiating the objects of the classes specified through the API, which it uses with reflection. For instance:
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; } }
The instance classes of the objects I want to create are implemented in Scala and parameterized on a type that has a context associated with it. For instance:
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) }
I encounter a problem when I pass this class to the Java environment to create new instances, as the framework makes the assumption that the class will have a constructor with a null argument. For example, the following code will NoSuchMethodException from inside 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)) }
An attempt to solve this problem is to add a constructor with a null argument to the OrderedValue , however there is no reasonable value for the implicit ord parameter. Setting null will result in a NullPointerException inside cmp :
def this() = this(null.asInstanceOf[A])(null.asInstanceOf[Ordering[A]])
Another approach is to subclass a specific concrete value of OrderedValue . For instance:
class OrderedIntValue(val v: Int) extends OrderedValue[Int](v) { def this() = this(null.asInstanceOf[Int]) } val a: OrderedValue[Int] = ReflectionUtil.newInstance(classOf[OrderedValue[Int]])
This will work, but not ideal, since it is not always convenient or possible to find out the specific type of OrderedValue . For example, newInstance can be called within the scope, which is also parameterized by type (i.e., we donβt know what it is specifically Int ).
So my question is: given that context boundaries (i.e. type classes) are a very useful and now widely used function inside Scala, and given that I cannot change the internals of the Java structure I'm interacting with, did anyone come across or developed an approach that can make it all work?