• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

108
Views
How does exactly as? behave in kotlin?

I was wondering why, since if (x is MyGeneric<Int>) { ... } will crash due to type erasure, as? works. I mean, couldn't A is B be implemented as (A as? B).let { if (it == null) false else true } ? If yes, why can't is checks work against generics, if no, what does differ ?

about 3 years ago · Santiago Trujillo
2 answers
Answer question

0

When you cast a class that has generic types, the cast will always succeed if the generic type is the only thing that is wrong. And type erasure, which you seem to be familiar with, is the reason. At runtime, a List<String> and a List<Foo> are exactly the same thing because of type erasure so casting between them will always succeed.

So a safe cast does not protect you from getting the generic type wrong, only the class type.

about 3 years ago · Santiago Trujillo Report

0

as? works

No it does not. as? does not return null, even when the generic type arguments are not compatible:

val strings = listOf("x", "y")
val ints = strings as? List<Int>

The above code will compile and run without any errors. It will only throw an exception, when you actually take things out of ints, and try to use them as Ints. The reason why this happens is, as you said, type erasure.

is could have been designed to work the same way as as? - evaluating to true even when the generic type arguments are not compatible:

val strings = listOf("x", "y")
strings is List<Int> // this could be designed to evaluate to true

The designers of Kotlin decided to disallow x is Foo<T>, but allow x as? Foo<T>.

After all, "checking the type" and "type conversion" come with different expectations. If you are asking me if an instance of List<Int> is of type List<Int>, you'd be very unexpected if I said yes. On the other hand, if you are asking me to convert an instance of List<Int> to a List<String>, and I successfully did it (albeit without checking the list's contents), that's not as unexpected. After all, I did what you asked for.

Now to answer your question:

I mean, couldn't A is B be implemented as (A as? B).let { if (it == null) false else true }? If yes, why can't is checks work against generics?

It could, but this would produced some rather unexpected behaviours, as discussed in the previous paragraph. Therefore, it is designed to not allow it.

about 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error