Java & Kotlin casting with generics. Losing typesafety -


when coding in kotlin/java, stumbled onto rather odd while using casting , generics. seems possible have type system believe list of type list<foo>, while list<object>.

can explain me why possible?

here example in both kotlin , java of issue:

example in kotlin

fun <t> test(obj: any): list<t> {     val ts = arraylist<t>()     ts.add(obj t)     return ts }  fun <t> test2(obj: any): t {     return obj t }  fun <t> test3(obj: any): list<t> {     val ts = arraylist<t>()     ts.add(test2(obj))     return ts }   fun main(args: array<string>) {     val x = test<double>(1) // returns list of integers , doesn't error     println(x)      val y = test2<double>(1) // casts int object double.     println(y)      val z = test3<double>(1) // returns list of integers , doesn't error.     println(z) } 

example in java

public class test {     public static <t> list<t> test(object obj){         arraylist<t> ts = new arraylist<>();         ts.add((t) obj);         return ts;     }      public static <t> t test2(object obj){         return (t) obj;     }      public static <t> list<t> test3(object obj){         arraylist<t> ts = new arraylist<>();         ts.add(test2(obj));         return ts;     }       public static void main(string[] args) {         list<double> x = test(1); // returns list of integers , doesn't error         system.out.println(x);          // double y = test2(1); // errors in java integers cannot converted double.         // system.out.println(y);          list<double> z = test3(1); // returns list of integers , doesn't error.         system.out.println(z);     } } 

java doesn't have reified generics. is, generic information not exist @ runtime, , generic code "simplified" process called erasure. compiler throws in casts when generic types known ensure correctness. can't cast generic type, then, generic types don't exist enough runtime know whether value 1 or not, , why javac yells @ doing this, because knows asking jvm cannot possibly do, introducing runtime unsafety.

public class test {     public static list test(object obj) { // generic types => erasure = raw types         arraylist ts = new arraylist();         ts.add(obj); // no cast: list.add has erasure (ljava.lang.object;)v         return ts;     }      public static object test2(object obj) { // t unbounded => erasure = object         return obj; // no cast: types <: object     }      public static list test3(object obj) {         arraylist ts = new arraylist();         ts.add(test2(obj)); // note: don't know t is, can't cast , ensure test2 returned one.         return ts;     }       public static void main(string[] args) {         list x = test(1); // returns list , doesn't error         system.out.println(x);          double y = (double) test2(1); // errors in java integer cannot converted double         // because compiler needs insert casts make generics work         system.out.println(y);          list z = test3(1);         // unlike y, there isn't cast in test3 because test3 doesn't know t is, integer passes through, uncast, list<double>.         // jvm can't detect this, because doesn't know list<double> is.         system.out.println(z);     } } 

note how test2 erases glorified identity function, causing test3 same thing test1, level of indirection.


Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -