title: Java & Kotlin casting with generics. Losing typesafety
body: <p>When coding in Kotlin/Java, I stumbled onto something rather odd while using casting and generics.
  It seems to be possible to have the type system believe a list is of the type <code>List&lt;Foo&gt;</code>, while it is actually a <code>List&lt;Object&gt;</code>.</p>
  
  <p>Can anyone explain to me why this is possible?</p>
  
  <p>Here is an example in both Kotlin and Java of the issue:</p>
  
  <p>Example in Kotlin</p>
  
  <pre><code>fun &lt;T&gt; test(obj: Any): List&lt;T&gt; {
      val ts = ArrayList&lt;T&gt;()
      ts.add(obj as T)
      return ts
  }
  
  fun &lt;T&gt; test2(obj: Any): T {
      return obj as T
  }
  
  fun &lt;T&gt; test3(obj: Any): List&lt;T&gt; {
      val ts = ArrayList&lt;T&gt;()
      ts.add(test2(obj))
      return ts
  }
  
  
  fun main(args: Array&lt;String&gt;) {
      val x = test&lt;Double&gt;(1) // Returns a list of Integers and doesn't error
      println(x)
  
      val y = test2&lt;Double&gt;(1) // Casts the Int object to a Double.
      println(y)
  
      val z = test3&lt;Double&gt;(1) // Returns a list of Integers and doesn't error.
      println(z)
  }
  </code></pre>
  
  <p>Example in Java</p>
  
  <pre><code>public class Test {
      public static &lt;T&gt; List&lt;T&gt; test(Object obj){
          ArrayList&lt;T&gt; ts = new ArrayList&lt;&gt;();
          ts.add((T) obj);
          return ts;
      }
  
      public static &lt;T&gt; T test2(Object obj){
          return (T) obj;
      }
  
      public static &lt;T&gt; List&lt;T&gt; test3(Object obj){
          ArrayList&lt;T&gt; ts = new ArrayList&lt;&gt;();
          ts.add(test2(obj));
          return ts;
      }
  
  
      public static void main(String[] args) {
          List&lt;Double&gt; x = test(1); // Returns a list of Integers and doesn't error
          System.out.println(x);
  
          // Double y = test2(1); // Errors in java an Integers cannot be converted into a Double.
          // System.out.println(y);
  
          List&lt;Double&gt; z = test3(1); // Returns a list of Integers and doesn't error.
          System.out.println(z);
      }
  }
  </code></pre>