在使用 Kotlin/Java 编码时,我在使用强制转换和泛型时偶然发现了一些相当奇怪的东西。似乎有可能让类型系统相信一个列表是该类型的List<Foo>
,而它实际上是一个List<Object>
.
谁能向我解释为什么这是可能的?
这是该问题的 Kotlin 和 Java 示例:
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)
}
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);
}
}