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
Post a Comment