开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜