tags:

views:

62

answers:

3

I usually end up trying every combination until it compiles. Can somebody explain what I should use where?

+1  A: 

Any and AnyVal are, I believe, part of the scala type system and are not classes as such (in the same way that Nothing is a type, not a class). You cannot use them explicitly from within Java code.

Howwever, in Java/Scala interoperation, a method which accepts a Java Object will expect a scala Any / AnyRef.

What are you actually attempting to do?

oxbow_lakes
I'm trying to understand this topic better so that I know what type I should be using when I'm planning to have Java call Scala or vice versa. This answer http://stackoverflow.com/questions/2334200/transforming-scala-varargs-into-java-object-varargs/2334331#2334331 and its cast to `AnyRef` just reminded me that this was still mysterious to me.
huynhjl
+1  A: 

Seen this? The text of the page has some java interoperability remarks. http://www.scala-lang.org/node/128

Scala Class Heirarchy

Mitch Blevins
+5  A: 

I'll disagree with Chris's answer in one regard. The classes Any, AnyRef and AnyVal are classes. But they don't appear as classes in bytecode, because of intrinsic limitations of the JVM.

This arises out of the fact that everything in Java is an object. There are objects, and, then, there are primitives. All objects in Java are descendant from java.lang.Object, but primitives are set apart and, presently*, not extensible by a programmer. Note also that primitives have "operators", not methods.

In Scala, on the other hand, everything is an object, all objects belong to a class, and they interact through methods. The JVM bytecode generated does not reflect this, but that doesn't make them any less so, just as Java has generics, even though the bytecode doesn't have them.

So, in Scala, all objects are descendant from Any, and that includes both what Java considers objects and what Java considers primitives. There's no equivalent in Java because there is no such unification.

Everything that is consider a primitive in Java is descendant from AnyVal in Scala. Because AnyVal is sealed, programmers are unable to extend it -- which, of course, would not be possible in the JVM. It should be interesting to see what will happen with Scala on .Net, since interoperability alone calls for Scala to at least recognize user-defined "primitives".

Also extending Any is AnyRef, which is equivalent to java.lang.Object (on the JVM at any rate).

Now, even though a user cannot extend Any or AnyVal, nor reference them from Java, there are uses they can be put to in Scala. Specifically, type signatures:

def f(x: AnyVal) = println(x)
def g(x: AnyRef) = println(x)
def h(x: Any) = println(x)

What each means should be obvious from the class hierarchy. Of note, however, is that f and h will auto-box, but g will not. That is a bit the opposite of what Java does, in that f and h cannot be specified, and g (defined with java.lang.Object) would cause auto-boxing.

  • In my own view, Java is likely to follow C# in allowing "struct" primitives, and maybe typedefs, as parallelism without resorting to them is proving difficult to accomplish with good performance.
Daniel