wired scala type design
my env is :
Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_26).
watch this example first:
scala> var a = 1
a: Int = 1
scala> var c = 'c
c: Symbol = 'c
scala> var d = 1.1
d: Double = 1.1
scala> var b = "123"
b: java.lang.String = 123
scala> val e:String = "234"
e: String = 234
so, you can see the other literal exc开发者_JAVA技巧ept string, the default type are Scala Types(Int Double Symbol
.
but the string literal is Java type.(java.lang.String
and when you define a value with the scala type String
, the String literal will be the type Scala String.
why the string literal's default type isn't Scala String?
Second:
when you must call scala method from java.
and your scala method with Parameter like this:
def hello(i:Int) = {
println(i)
}
on java side . if you call like this.
object.hello(null)
it will fail by type mismatch.
the java.lang.Integer
can be null. but the scala Int
can't be null.
null in scala is the subtype of AnyRef. not AnyVal..
i found that AnyRef and AnyVal take me to the java1.4 world, which dose not have autobox.. .
Answer to your first question:
scala.String
is simply a type synonym defined in Prelude
Predef
for good old java.lang.String
. (Unlike scala.Int
, scala.Float
etc. which are distinct types from java.lang.Integer
, java.lang.Float
etc.)
This might help: (Observe the types.)
scala> def f(s: String) = s * 2
f: (s: String)String
scala> f("hello")
res7: String = hellohello
scala> def f(s: String): java.lang.String = s * 2
f: (s: String)java.lang.String
scala> f("hello")
res8: java.lang.String = hellohello
scala> type Str = String
defined type alias Str
scala> def f(s: String): Str = s * 2
f: (s: String)Str
scala> f("hello")
res9: Str = hellohello
missingfaktor has answered the first question you have.
For the second part of your question: Scala.Int is different to java.lang.Integer, it is really an alias for a java int, and has pretty much the same behaviour:
scala> def print(i: Int) = println(i + " class=" + i.getClass.getName)
print: (i: Int)Unit
scala> print(43)
43 class=int
So scala treats scala.Int as int where possible. Note that autoboxing/unboxing occurs as normal.
scala> print(new java.lang.Integer(666))
666 class=int
So actually, it does not make sense to pass a null to a method which is expecting an int. This is a compilation error in Java as well.
private void setInt(int i) {}
setInt(null); // compilation error
If you force a null java.lang.Integer to be passed where an int is expected, then you get a NullPointerException. This is exactly the same behaviour as Java.
scala> val f: java.lang.Integer = null
f: java.lang.Integer = null
scala> print(f)
java.lang.NullPointerException
....
If you want to create a scala method which takes a nullable object, declare it to take java.lang.Integer. The autoboxing/unboxing behaviour will be exactly the same as for Java.
scala> def print(i: java.lang.Integer) = println(i + " class=" + i.getClass.getName)
print: (i: java.lang.Integer)Unit
scala> print(43)
43 class=java.lang.Integer
scala> print(new java.lang.Integer(666))
666 class=java.lang.Integer
精彩评论