对Java规范中的泛型子类型感到困惑吗?

时间:2018-07-20 02:35:25

标签: java subtyping

我正在阅读Java规范 https://docs.oracle.com/javase/specs/jls/se10/html/jls-4.html#jls-4.10.2 这行使我感到困惑:

  

D<U1 θ,...,Uk θ>,其中D<U1,...,Uk>是通用类型,是   通用类型C的直接超类型,θ为   替换[F1:= T1,...,Fn:= Tn]。

Uk θ在这里投射吗?替换后D变成D<(U1)T1,...,(Uk)Tk>吗?如果是这样,为什么作者在转换语法中省略了Uk θ中的括号?谢谢!

2 个答案:

答案 0 :(得分:1)

不投放。这是用来描述类型的数学语言。

在代码中,它表示:

interface D<A, B> {}
interface C<A, B> extends D<A, B> {}

class Y implements D<String, Number> {}
class X implements C<String, Integer> {} // Note Integer is a subtype of Number

然后编译:

D d = new X();

答案 1 :(得分:1)

  

给出通用类型声明C<F1,...,Fn>(n> 0),直接   参数化类型C<T1,...,Tn>的超类型,其中Ti(1≤i≤   n)是一种类型,是否所有以下内容:

     

D<U1 θ,...,Uk θ>,其中D<U1,...,Uk>是通用类型,是   通用类型C<F1,...,Fn>的直接超类型,并且θ是   替换[F1:= T1,...,Fn:= Tn]。

让我们看一个例子。

public class D<U1,U2> {
}

//Note the order of F3,F4.
class C<F1,F2,F3,F4> extends D<F4,F3>{

}

class Main{

    public static void main(String[] args) {

        C<Integer,String,Float,Number> obj = new C<>();

        D<Float ,Number> obj2 = obj; // Compilation error

        D<Number ,Float> obj3 = obj; //This is fine


    }
}

您认为θ在这里吗?

θ = [F1:=整数,F2:=字符串,F3:=浮点数,F4:=数字]

现在D<Number,Float>是正确的超类型。但不是D<Float,Number>。为什么?

由于Ui θ。那是什么意思呢?

好吧,这仅表示替代,即扫描U1 , U2 , ... till Uk,如果找到任何Fi,然后将其替换为Ti

在我们的示例中,这意味着扫描D类的F4F3。您是否在θ中拥有F4F3?是。 然后F4中的F3D 必须是θ中定义的

注意:答案是根据我的理解。我没有关于Uk θ在Java类型语义中的含义的具体参考。