Java and kotlin. Loss of type safety

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 List<Foo>, while it is actually a List<Object>.

Can anyone explain to me why this is possible?

Here is an example in both Kotlin and Java of the issue:

Example in Kotlin

fun <T> test(obj: Any): List<T> {
    val ts = ArrayList<T>()
    ts.add(obj as T)
    return ts
}

fun <T> test2(obj: Any): T {
    return obj as 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 a list of Integers and doesn't error
    println(x)

    val y = test2<Double>(1) // Casts the Int object to a Double.
    println(y)

    val z = test3<Double>(1) // Returns a list of Integers and 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 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<Double> z = test3(1); // Returns a list of Integers and doesn't error.
        System.out.println(z);
    }
}
This question and all comments follow the "Attribution Required."

All Answers

Answers Loading...
Leave a Reply
You must be logged in to post a answer.
About the author