编程语言
首页 > 编程语言> > 在Java中键入数组和泛型的规则

在Java中键入数组和泛型的规则

作者:互联网

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

Arrays and generics have very different type rules. Arrays are covariant and reified; generics are invariant and erased.

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

解决方法:

你没有提到你是否对某一特定概念感到困惑,所以我将尝试给出协方差和不变性的基本定义.

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

所以,如果你有以下课程

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);

换句话说,数组类型将暴露给运行时或已实现.

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

但是,您仍然可以分别使用extends和super在Java中明确表达协方差和逆变.例如与班级

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);

标签:java,covariance,generics,erasure
来源: https://codeday.me/bug/20190623/1272766.html