Shailendra Madda
Shailendra Madda

Reputation: 21561

Convert Any to Long in kotlin

I am trying to convert the Any type of an Object to Long, but it is showing the following exception:

java.lang.ClassCastException : java.lang.Object[] cannot be cast to java.lang.Long

Here I want to cast the any to Long like below:

    fun getMyLongValue(vararg any: Any) : Long {
    return when(val tmp = any.first()) {
        is Number -> tmp.toLong()
        else -> throw Exception("not a number")
    }
}

I am passing params to it like:

    fun main() { 
    val param1 = 10
    val param2 = 20
    println(getMyValue(param1.toLong(), param2.toLong())) 
}

fun getMyValue(vararg any: Any): Long {
    return getMyLongValue(any)
}

Upvotes: 0

Views: 7010

Answers (2)

Alexey Romanov
Alexey Romanov

Reputation: 170899

I am passing Int values but I want to cast to Long. Then why it's not allowing?

Because of boxing. Any corresponds to Java Object, so all primitives are boxed when passed to getMyLongValue. And you can't cast a boxed Int (java.lang.Integer) to Long. You'll need to handle primitives separately, or use the fact that boxed Int/Long/etc. extend Number, e.g.

fun getMyLongValue(vararg any: Any) : Long {
    return when(val tmp = any.first()) {
        is Number -> tmp.toLong()
        else -> throw Exception("not a number") // or do something else reasonable for your case
    }
}

EDIT:

This problem is not related to converting to Long. When you write

fun getMyLongValue(vararg any: Any) { ... }

fun getMyValue(vararg any: Any): Long {
    return getMyLongValue(any)
}

you pass the entire any from getMyValue as a single argument (of type Array<Any>). To pass 10 and 15 (or other arguments of getMyValue) separately, you need to use the spread operator:

fun getMyValue(vararg any: Any): Long {
    return getMyLongValue(*any)
}

Upvotes: 6

user28434&#39;mstep
user28434&#39;mstep

Reputation: 6600

You can't just use as Long here. Because it would always fail unless you pass Long parameter.

You should toLong() function to convert. But it's not method of Any. So you will have to get rid of Any type specification.

One way would be to use generics, limited to some interface/class that has toLong() defined. Like Number.

fun <T: Number> getMyLongValue(vararg any: T) : Long {
    val myVal = any.first().toLong()
    return myVal
}

It will definetely work for

getMyLongValue(15, 10)

But may not work for your real data, if it would have non-numeric "input".


Also, why are you using vararg if you just using the first element?

Either drop it, or handle all values:

fun <T: Number> getMyLongValue(vararg any: T) : List<Long> {
    val myVal = any.map { it.toLong() }
    return myVal
}

Upvotes: 2

Related Questions