4

在 Effective Java (2nd) 中第 25 条的最后一段中,它说:

数组和泛型有非常不同的类型规则。数组是协变具体化的;泛型是不变的和被擦除的。

有人可以更好地定义与 Java 中的数组和泛型相关的粗体术语吗?我也不介意一些例子。

4

1 回答 1

4

您没有提到您是否对某个特定概念感到困惑,所以我将尝试仅给出covarianceinvariance的基本定义。

协方差保留类型顺序,不变性不保留。这意味着子类型是否保留(在逆变的情况下反转)。

所以,如果你有以下课程

public class A {

  public void go() {

    System.out.println("A");
  }
}

和...

public class B extends A {

  @Override
  public void go() {

    System.out.println("B");
  }
}

使用协变类型(例如数组),函数

public static void go(A[] as) {

  for (A a : as)
    a.go();
}

完全有效用作

A[] as = new A[8];
B[] bs = new B[8];

go(as);
go(bs);

换句话说,数组类型暴露给运行时或reified

对于不变类型(例如泛型),不保留子类型。因此,例如,与以外X<B>没有类型关系。这部分是泛型类型没有暴露给运行时或被擦除的结果。X<A>X

但是,您仍然可以分别使用和在 Java 中显式地表达协变逆变。例如与类extendssuper

public class X<T extends A> {

  private T t_;

  public X(T t) {
   t_ = t;
  }

  public void go() {

    t_.go();
  }
}

功能

public static void go(X<?> x) {

  x.go();
}

将有效用作

X<A> xa = new X<A>(a);
X<B> xb = new X<B>(b);

go(xa);
go(xb);
于 2015-08-18T19:34:22.853 回答