views:

702

answers:

2

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?

+6  A: 

I found my own answer. The equivalent is

val g = new SimpleGraph[String, DefaultEdge](classOf[DefaultEdge])
mtnygard
+12  A: 

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

James Iry