When casting a String to the type Any, it will no more be considered automatically as String — why ? See the following example:
val str = "foo"
val strAsAny = "bar".asInstanceOf[Any]
def f1(x: String) = println(x.toString)
def f2(x: Any) = println(x.toString)
f1(str) // works, type exactly given
f2(str) // works, subtype of Any given
f1(strAsAny) // works not, but strAsAny.isInstanceOf[String] = true !
f2(strAsAny) // works, type exactly given
This confuses me a bit, because both values do still have the type String :
scala> str.isInstanceOf[String]
res4: Boolean = true
scala> strAsAny.isInstanceOf[String]
res5: Boolean = true
My guess is, that only type conversions “to get upwards” of the interhitance-chain will be done automatically. Is this correct ?
You are conflating static types with dynamic types.
A static type is what the compiler knows, and is something that exists at compile time.
That is, when you do this:
Then the compiler will know (or think) that
strAsAnyhas typeAny. It won’t know there’s aStringstored in there.Mind you, avoid as much as possible
asInstanceOf, since most valid uses of it can be replaced by type ascription ("bar" : Any) or pattern matching (case anyAsStr: String => "got a String"), both of which are safe. The operatorasInstanceOfis not safe, because it tells the compiler to ignore what it knows, and believe what you are telling it, even when it knows it’s wrong.So,
asInstanceOfis mostly a compile-time operator, though it also produces some code for the JVM to execute.Now, what the compiler thinks matter because it only let you call methods it knows can be called. So even though, at run time,
strAsAnywill contain aString, the compiler doesn’t know that. You told it to forget that"bar"is aString, and it did so. Therefore, you are not allowed to callStringmethods on it.On the other hand, a dynamic type is what is true at run time. In most cases, for a language like Scala, the compiler has no way of knowing what will be true or not at run time.
And whether the compiler can know something or not,
isInstanceOfis a run time operation. The compiler doesn’t have anything to say about what will happen.So, when you do this:
The compiler doesn’t care — it just compiles the code. When you execute the code, then the JVM will verify what kind of value is stored inside
strAsAny, and verify that it is, indeed, aString, and then returntrue.