Kotlin中的Java超类和子类泛型



我正在寻找Kotlin中有关Java泛型的文档或规范。
我对父类和子类之间的不同行为很好奇。

例如,下面是Java代码:
// A.java
public class A<T> {
public T value;
public A(T value) {
this.value = value;
}
}
// B.java
public class B<T> extends A<T> {
public B(T value) {
super(value);
}
}

从Kotlin中使用上面的Java代码。

fun main() {
val a = A<String>("a")
val b = B<String>("b")
val aValue = getValue(a)
val bValue = getValue(b)
// lint error: Condition 'aValue == null' is always 'false'
// aValue is non-null type
println(aValue == null)
// No lint error
// bValue is platform type(String!)
println(bValue == null)
}
fun <T> getValue(a: A<T>): T {
return a.value
}

在这种情况下,对于超类,函数的结果被标记为非空。
另一方面,对于子类,函数的结果被标记为平台类型。

有人知道这个规范吗?
如果你能告诉我有关官方文件等,那就太有帮助了。

编译器可以判断出aValue == null总是假的,因为aValue的类型是A<String>,经过类型推断,getValue的类型参数T推断为不可空的String。注意,这里的T不能是String?,因为A<String>不是A<String?>的子类型,就像List<Dog>不是List<Animal>一样。因此,StringgetValueaValue的返回值。

另一方面,bValue类型为B<String>。关于类型参数T,类型推断说了什么?T可以是String或者String?B<T>可以继承A<T>,T是非空的,但B<T>也可以继承A<T?>,不是吗?Java代码中没有注释说明这一点。因此,Kotlin编译器选择谨慎,将T推断为String?,假定B<T>继承自A<T?>

如果您的意思是B<T>继承自A<T>,请在Java代码中用Kotlin能够识别的注释之一标记:

class B<T> extends A<@NotNull T> {

如果您无法控制Java代码,您还可以显式指定类型参数:

val bValue = getValue<String>(b)

由于平台类型是特定于平台的,它们不在Kotlin/Core规范中。这种特定的行为可能会出现在尚未发布的Kotlin/JVM规范中:(