6

Because I know a little bit Java I was trying to use in every Scala Code some Java types like java.lang.Integer, java.lang.Character, java.lang.Boolean ... and so on. Now people told me "No! For everything in Scala there is an own type, the Java stuff will work - but you should always prefer the Scala types and objects".

Ok now I see, there is everything in Scala that is in Java. Not sure why it is better to use for example Scala Boolean instead of Java Boolean, but fine. If I look at the types I see scala.Boolean, scala.Int, scala.Byte ... and then I look at String but its not scala.String, (well its not even java.lang.String confuse) its just a String. But I thought I should use everything that comes direct from scala. Maybe I do not understand scala correctly, could somebody explain it please?

sabisabi
  • 1,501
  • 5
  • 22
  • 40
  • 4
    May be this topic will help you to understand this moment: http://stackoverflow.com/questions/6559938/scala-string-vs-java-lang-string-type-inference – Sergey Vedernikov Nov 27 '12 at 08:21

2 Answers2

12

First, 'well its not even java.lang.String' statement is not quite correct. Plain String name comes from type alias defined in Predef object:

type String = java.lang.String

and insides of Predef are imported in every Scala source, hence you use String instead of full java.lang.String, but in fact they are the same.

java.lang.String is very special class treated by JVM in special way. As @pagoda_5b said, it is declared as final, it is not possible to extend it (and this is good in fact), so Scala library provides a wrapper (RichString) with additional operations and an implicit conversion String -> RichString available by default.

However, there is slightly different situation with Integer, Character, Boolean etc. You see, even though String is treated specially by JVM, it still a plain class whose instances are plain objects. Semantically it is not different from, say, List class.
There is another situation with primitive types. Java int, char, boolean types are not classes, and values of these types are not objects. But Scala is fully object-oriented language, there are no primitive types. It would be possible to use java.lang.{Integer,Boolean,...} everywhere where you need corresponding types, but this would be awfully inefficient because of boxing.
Because of this Scala needed a way to present Java primitive types in object-oriented setting, and so scala.{Int,Boolean,...} classes were introduced. These types are treated specially via Scala compiler - scalac generates code working with primitives when it encounters one of these classes. They also extend AnyVal class, which prevents you from using null as a value for these types. This approach solves the problem with efficiency, leaves java.lang.{Integer,Boolean,...} classes available where you really need boxing, and also provides elegant way to use primitives of another host system (e.g. .NET runtime).

Vladimir Matveev
  • 120,085
  • 34
  • 287
  • 296
4

I'm just guessing here

If you look at the docs, you can see that the scala version of primitives gives you all the expected operators that works on numeric types, or boolean types, and sensible conversions, without resorting to boxing-unboxing as for java.lang wrappers.

I think this choice was made to give uniform and natural access to what was expected of primitive types, while at the same time making them Objects as any other scala type.

I suppose that java.lang.String required a different approach, being an Object already, and final in its implementation. So the "path of least pain" was to create an implicit Rich wrapper around it to get missing operations on String, while leaving the rest untouched.

To see it another way, java.lang.String was already good enough as-is, being immutable and what-else.

It's worth mentioning that the other "primitive" types in scala have their own Rich wrappers that provides additional sensible operations.

pagoda_5b
  • 7,333
  • 1
  • 27
  • 40