var a : Double
a = Math.sin(10) // error: the integer literal does not conform to the expected type Double
a = Math.sin(10.0) //This compiles successfully
println(a)
Automatic type casting for numeric types can lead to losing precision. Just consider following java code:
double hoursSinceUnixEra = System.currentTimeMillis()/1000/60/60;
The intention was not to cut the result to full hours, although it compiles without any warning in Java.
val hoursSinceUnixEra = System.currentTimeMillis()/1000/60/60;
someObject.doubleValue = hoursSinceUnixEra
Above Kotlin code won't compile due to unexplicit casting.
Issue of this type can be very hard to find and fix and it's the reason behind this decision. You can still explicitly convert type:
val value = 3
Math.sin(value.toDouble())
We all know that Kotlin has both non-nullable Int
and nullable Int?
.
When we use Int?
this happens: Kotlin actually 'boxes' JVM primitives when Kotlin needs a nullable reference since it's aimed at eliminating the danger of null references from code.
Now look at this: (assuming this is a compilable code)
val a: Int? = 1
val b: Long? = a
Kotlin doesn't perform implicit type conversion because of this thing happens. If Kotlin did implicit type conversions, b
should be 1
. but since a
is a boxed Int
and b
is a boxed Long
, a == b
yields false
and falls into contradiction, since its ==
operator checks for equals()
and Long
's equals()
checks other part to be Long
as well.
Check the documentation:
Kotlin does not allow implicit conversions of numeric types. There is a misconception that implicit conversions are "no harm, no foul" ... which is wrong.
The process in Java for implicit conversions is more complicated than you think, read the docs to see what all is entailed. And then you can try to analyze all of the cases that can go wrong.
Kotlin, does not want the compiler to guess as to your intention, so it makes everything in the language explicit, including numeric type conversions. As explained in the Kotlin docs for Explicit Conversions it says clearly:
Due to different representations, smaller types are not subtypes of bigger ones. [...] As a consequence, smaller types are NOT implicitly converted to bigger types. [...] We can use explicit conversions to widen numbers.
And the documentation shows one such sample of where things can go wrong, but there are many others.
Nor can you just cast one numeric type to another, as mentioned here in incorrect comments and answers. That will only result in a nice runtime error. Instead look at the numeric conversion functions such as toInt()
and toDouble()
found on the numeric types, such as on the Number class.
Explicitness is part of the Kotlin personality, and it is not planned to change.