Reputation:
I'm trying to use a Java class library from Scala code. (JGraphT, to be precise.) One of the constructors I need to call is
public class SimpleGraph<V, E>
extends AbstractBaseGraph<V, E>
implements UndirectedGraph<V, E>
{
public SimpleGraph(Class<? extends E> edgeClass) {...}
}
To call this from Java, I would say:
UndirectedGraph<String, DefaultEdge> g = new SimpleGraph<String, DefaultEdge>(DefaultEdge.class);
What's the correct Scala equivalent?
More specifically, how do I pass the DefaultEdge.class argument to the constructor?
Upvotes: 10
Views: 3936
Reputation:
I found my own answer. The equivalent is
val g = new SimpleGraph[String, DefaultEdge](classOf[DefaultEdge])
Upvotes: 9
Reputation: 19367
The equivalent Scala code is, as you say
val g: UndirectedGraph[String, DefaultEdge] = new SimpleGraph[String, DefaultEdge](classOf[DefaultEdge])
But that can DRYed up a bit because Scala can infer the type parameters of your constructor
val g: UndirectedGraph[String, DefaultEdge] = new SimpleGraph(classOf[DefaultEdge])
But that's not as DRY as it can get. The "DefaultEdge" type gets mentioned twice. You can get even more DRY with manifests. First you create a factory for creating SimpleGraphs.
object SimpleGraph {
import scala.reflect.Manifest
def apply[T, E]()(implicit mfst : Manifest[E]) = new SimpleGraph[T,E](mfst.erasure.asInstanceOf[Class[_ <: E]])
}
And with this we can create a graph with either
val g = SimpleGraph[String, DefaultEdge]()
or
val g: UndirectedGraph[String, DefaultEdge] = SimpleGraph()
Obviously this technique is only worth it if you create a bunch of SimpleGraphs
Now some caveats and warnings. Manifests are still considered experimental. I suspect they're too useful to ever be dropped, but there are no guarantees. For more about manifests see http://scala-blogs.org/2008/10/manifests-reified-types.html
Upvotes: 19