tags:

views:

82

answers:

3

I'm new to scala. I tried this code:

val name = "mike"
println(name.getClass())

It's OK and printed java.lang.String

But, when I try:

val num = 123
println(num.getClass())

There is such a compiler error:

type mismatch; found : Int required: ?{val getClass: ?} Note: primitive types are not implicitly 
 converted to AnyRef. You can safely force boxing by casting x.asInstanceOf[AnyRef].

I remember scala said "Everything is object in scala", why can't I invoke num.getClass()? And how to fix it?

+3  A: 

Everything is object doesn't mean every object has a method getClass. As the compiler says, 123.asInstanceOf[AnyRef].getClass would work.

Eastsun
@Eastsun, thanks for your answer. I just learn scala 2 days, I know little about scala. I thought it had a "getClass()", because I thought every object should extend from java.lang.Object. And, do you mean, in scala, not every object extends from java.lang.Ojbect?
Freewind
+4  A: 

The getClass method is only available for reference classes (i.e. sacala.AnyRef). 123 is member of a value class (i.e. scala.Any) and thus does not have a getClass method.

See http://www.scala-lang.org/node/128 for the Scala object hierarchy. And www.scala-lang.org/docu/files/api/scala/AnyRef.html for AnyRef.

michid
Value classes are not direct subclasses of scala.Any, but scala.AnyVal...
Sandor Murakozi
+5  A: 

Yep, everything is an object, but not necessary an instance of a java class/something with a getClass() method :)

Java primitive values (and Unit) are AnyVals in scala (instances of so called value classes), and - whenever it's possible - they are compiled to Java primitives at the end. When it's not possible boxing is done (similar to auto boxing in Java). But - as the error reports - boxing did not happen ("implicitly") in your case. Value classes don't have a getClass() method -> compilation error.

Java classes are AnyRefs (an instance of a reference class = a class instance in Java). getClass will work fine on them: AnyRef is practically the same as java.lang.Object -> it also has a getClass() method that you can call.

As the error recommends you can force the boxing, then getClass() will work on it:

num.asInstanceOf[AnyRef].getClass

will print

class java.lang.Integer

If you want to avoid boxing (e.g. you want to differentiate between primitive and boxed values) have a look at HowTo get the class of _ :Any

Sandor Murakozi
@Sandor Murakozi, thank you so much!
Freewind