有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java中数组和泛型的类型规则

有效Java(2)第25项的最后一段说:

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

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


共 (1) 个答案

  1. # 1 楼答案

    您没有提到您是否对某个特定概念感到困惑,因此我将尝试给出协方差不变性的基本定义

    协方差保留类型排序,不变性不保留类型排序。这意味着子类型被保留或不被保留(在逆变的情况下倒置)

    那么,如果你上过下面的课

    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之外,与X<A>没有类型关系。这部分是由于泛型类型未暴露于运行时或已擦除

    但是,您仍然可以分别使用extendssuper在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);