代码之家  ›  专栏  ›  技术社区  ›  Thor

为什么Java中的类型变量是不可重构类型

  •  12
  • Thor  · 技术社区  · 8 年前

    我目前正在学习Java泛型,下面是Java中不可重用的类型列表。

    如果类型是以下类型之一,则该类型不可重设:

    _?A型变量 (例如 T )

    带有实际参数的参数化类型 (例如 List<Number>, ArrayList<String>, or Map<String, Integer> )

    _窆带界的参数化类型 (例如 List<? extends Number> or Comparable<? super String> )

    我理解为什么带有实际参数的参数化类型和带有绑定的参数化类型是不可重新调整的,因为在运行时擦除之后,剩下的唯一类型信息是 List ,但为什么类型变量(例如 T )不可再流通的类型?我在运行时想,在类型删除之后, T 会变成 Object (给出 T 是未绑定的类型参数),因此类型信息可用。

    我的理解有问题吗?

    2 回复  |  直到 8 年前
        1
  •  2
  •   Tobias    8 年前

    这个 docs 声明

    不可重设的类型没有 全部的 它的信息在运行时可用。

    的类型 T 在运行时是 Object 所以信息丢失了。丢失信息的一个例子是如何创建对象。考虑这个类:

    public class A {
        private int a;
        public A() {
            a = 5;
        }
    }
    

    现在看看这个 不编译 代码:

    public class Generic<T> {
        T foo() {
            return new T(); //Compiler Error!
        }
    }
    

    如果允许,并且您正在实例化 Generic<A> g = new Generic<>(); 和呼叫 g.foo() ,的构造函数 T 无法调用,因为在运行时, T 只被称为 对象 .因此,一个 A 无法创建和返回。您甚至不能确定哪个信息是 T 需要。信息如何 T 可构造丢失。

    这就是类型参数必须是不可重写类型的原因之一。

        2
  •  5
  •   Adam Perea    8 年前

    当一个对象的输入信息在编译时没有丢失时,它是可重设的。不允许对不可重设的对象执行某些操作。例如,我们不能 的实例。

    通用类型是不可重设的,这就是为什么我们不能这样做的原因

     List <Conference> instance
    

    这在某些情况下是可行的,但我们不能忘记JDK必须在一个版本和另一个版本之间向后兼容。这个约束解释了实现中的一些限制。

    Java类型是可表示的,如果它被表示。 完全在执行过程中(无擦除 类型):

     primitive type
     non-parametric type
     parametric type in which all arguments of type are unbounded jokers (List <?>)
     type "raw" (List)
     table whose type of elements is reifiable
    

    我不知道这是否对你有帮助,如果没有,我可以删除它,祝你愉快!