kotlin - Declaration-site variance may cause ClassCastException -


kotlin introduces declaration-site variance described @ here.

the out/in keywords generic parameters may cause classcastexception in case. program shown below.

fun main(args: array<string>) {     var l: list<string> = mutablelistof("string")     demo(l)     println("======")     (s in l) {         println(s)     } }  fun demo(strs: list<string>) {     val objects: list<any> = strs // ok, since t out-parameter     if (objects mutablelist) {         val obs: mutablelist<any> = objects mutablelist<any>         obs.add(textview())     } } 

output:

exception in thread "main" java.lang.classcastexception: com.kotlin.demo.clzz.textview cannot cast java.lang.string     @ com.kotlin.demo.clzz.declaration_site_variancekt.main(declaration-site-variance.kt:14) ====== adn 

is way use out/in keywords recommended practice? , why?

your code can compiled without warnings, because declaration-site variance available in kotlin.

this in contrast java's use-site variance wildcards in type usages make types covariant.

for example 2 soruce interfaces use declaration-site variance in kotlin:

interface source<out t>  interface source<in t>  

both of 2 source interfaces generated same source code in java below:

//                      v---`t extends object` rather `? extends t`  public interface source<t>{ /**/ } 

this because wildcard ? used type argument rather type parameter in java. t in source<t> type parameter , ? extends string in source<? extends string> type argument.

so if use type projections make objects force list<out any>, compiler reports unchecked_cast warning , example:

fun demo(strs: list<string>) {     //                v--- makes explicitly using out type proejction     val objects: list<out any> = strs      if (objects mutablelist) {          //                                 v--- unchecked_cast warning reported         val obs: mutablelist<any> = objects mutablelist<any>         obs.add(textview())     } } 

in other words, can't assign list<out any> mutablelist<any>. otherwise, compilation error. example:

fun demo(strs: list<string>) {     val objects: list<out any> = strs      if (objects mutablelist) {         //                                v--- ? extends object         //error: can't assign mutablelist<out any> mutable<any>          //                          v                          ^--- object         val obs: mutablelist<any> = objects         obs.add(textview())     } } 

if assign objects mutablelist<out any> variable, you'll found can't adding anything, since can't create nothing in kotlin @ all. example:

fun demo(strs: list<string>) {     val objects: list<out any> = strs     if (objects mutablelist) {         //                   v--- down-casting `mutablelist<out any>`          val obs: mutablelist<out any> = objects         //      v---error: can't instantiated         obs.add(nothing())     } } 

q: way use out/in keywords recommended practice?

java has described how use wildcard , applies in kotlin.

an "in" variable, note "in" in here ? extends t , same kotlin out variance:

an "in" variable serves data code. imagine copy method 2 arguments: copy(src, dest). src argument provides data copied, "in" parameter.

an "out" variable, note "out" in here ? super t , same kotlin in variance:

an "out" variable holds data use elsewhere. in copy example, copy(src, dest), dest argument accepts data, "out" parameter.


Comments

Popular posts from this blog

php - Vagrant up error - Uncaught Reflection Exception: Class DOMDocument does not exist -

vue.js - Create hooks for automated testing -

Add new key value to json node in java -