This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Help on Scala/Java integration

3 replies
mvackel
Joined: 2009-08-03,
User offline. Last seen 1 year 39 weeks ago.

Hello,

When using (Java) swing and Scala together I found this difference and
don't know what's happening. Can anyone please help?

Why is the Scala result different and how the Scala code should be
modified to give the same result as in Java?

Thank in advance,

Marcos

Lars Hupel
Joined: 2010-06-23,
User offline. Last seen 44 weeks 3 days ago.
Re: Help on Scala/Java integration

> TreePath tp = new TreePath(book.getPath());
> System.out.println(tp);
> ---------
> Result: [root, Twain, Huck]

`book.getPath()` returns `TreeNode[]`. The constructor of `TreePath`
takes `Object[]`. Now, for javac, these types are compatible and it
covariantly casts the array of `TreeNode` to an array of `Object`.

> ----- in Scala ---------------------------------------
> val tp = new TreePath(book.getPath())
> println(tp)
> ---------
> Result: [[Ljavax.swing.tree.TreeNode;@b5f53a]

For Scala, those types are not compatible such that it chooses the
constructor of `TreePath` taking an `Object`. (In Scala, arrays are
invariant.) There are two ways to address that:

1) tp.asInstanceOf[Array[Object]] (bad)
2) tp map { x => x: Object } (better)

mvackel
Joined: 2009-08-03,
User offline. Last seen 1 year 39 weeks ago.
Re: Help on Scala/Java integration

Hi Lars,

Thank you for answering.

The first suggestion, using an explicit cast worked fine.

The second option, using the map doesn't compile ("value map is not a
member of javax.swing.tree.TreePath").

I'm curious... why is the second version better? Seems worse, as there
will be another val to receive the map result or change the original
val to var...

Thanks,

Marcos

On Jan 24, 7:24 am, Lars Hupel wrote:
> >    TreePath tp = new TreePath(book.getPath());
> >    System.out.println(tp);
> > ---------
> > Result:   [root, Twain, Huck]
>
> `book.getPath()` returns `TreeNode[]`. The constructor of `TreePath`
> takes `Object[]`. Now, for javac, these types are compatible and it
> covariantly casts the array of `TreeNode` to an array of `Object`.
>
> > ----- in Scala ---------------------------------------
> >            val tp = new TreePath(book.getPath())
> >            println(tp)
> > ---------
> > Result:    [[Ljavax.swing.tree.TreeNode;@b5f53a]
>
> For Scala, those types are not compatible such that it chooses the
> constructor of `TreePath` taking an `Object`. (In Scala, arrays are
> invariant.) There are two ways to address that:
>
> 1) tp.asInstanceOf[Array[Object]] (bad)
> 2) tp map { x => x: Object } (better)

Lars Hupel
Joined: 2010-06-23,
User offline. Last seen 44 weeks 3 days ago.
Re: Help on Scala/Java integration

> The second option, using the map doesn't compile ("value map is not a
> member of javax.swing.tree.TreePath").

I made a mistake in writing it down.

>> 2) tp map { x => x: Object } (better)

It should read

new TreePath(book.getPath() map { x => ...

> I'm curious... why is the second version better? Seems worse, as there
> will be another val to receive the map result or change the original
> val to var...

I guess casting would be acceptable here, but casts circumvent the type
system and might introduce unsoundness into your program.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland