java - 阅读 Core Java 第 11 版时关于 **类型删除机制** 的问题

标签 java types casting type-conversion jvm

这是作者在书中提供的有关泛型编程的代码示例:

public class Pair<T>
{
  private T first;
  private T second;
  public Pair() { first = null; second = null; }
  public Pair(T first, T second) { this.first = first; this.second = second; }
  public T getFirst() { return first; }
  public T getSecond() { return second; }
  public void setFirst(T newValue) { first = newValue; }public void setSecond(T newValue) { 
  second = newValue; }
}

接下来作者介绍一下类型删除机制

Whenever you define a generic type, a corresponding raw type is automatically provided. The name of the raw type is simply the name of the generic type, with the type parameters removed. The type variables are erased and replaced by their bounding types (or For example, the raw type for Object for variables without bounds).

Your programs may contain different kinds of erasure turns them all into raw Pair , such as Pair<String> or Pair<LocalDate> , but erasure turns them all into raw Pair types.

对于 class Pair<T> 的情况,删除后就变成下面的原始Pair类型:

public class Pair
{
  private Object first;private Object second;
  public Pair(Object first, Object second)
  {
  this.first = first;
  this.second = second;
  }
  public Object getFirst() { return first; }
  public Object getSecond() { return second; }
  public void setFirst(Object newValue) { first = newValue; }
  public void setSecond(Object newValue) { second = newValue; }
}

因此,如果我们运行下面的代码,则会打印 TURE

Pair<Integer> p = new Pair<Integer>(1, 2);
Pair<String> s = new Pair<String>("a", "b");
System.out.println(p.getClass()==s.getClass());

问题来了,当我创建 Pair<T> 的实例时类型错误,例如:

 Pair<String> s = new Pair<String>("a", 1);

编译器可以找出问题并打印以下消息:

pair1/PairTest1.java:12: error: incompatible types: int cannot be converted to String Pair s = new Pair("a", 1);

sice <T>被删除为Object,构造函数就变成了:

public Pair(Object first, Object second)
  {
  this.first = first;
  this.second = second;
  }

并且参数类型变为Object,所以:

编译器如何确定类型错误?什么时候类型删除发生?

最佳答案

当编译器生成字节代码时会发生类型删除,但编译器在验证源代码时知道泛型类型。此时尚未删除任何内容。

但是,编译器知道即使在验证期间也会发生删除。例如。如果你重载这样的方法:

void doStuff(List<Integer> intList) {}
void doStuff(List<String> stringList) {}

编译器知道删除后两者都将是 void doStuff(List xxx) {},并且两个方法不能具有相同的签名1,因此即使类型删除尚未发生,验证步骤也会生成错误消息。

1) 参数名称不是签名的一部分

关于java - 阅读 Core Java 第 11 版时关于 **类型删除机制** 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60593267/

相关文章:

java - Spring Shell - 使用和执行

java - 使用 char 数组接收用户输入并使用数组逐个元素向用户显示

exception - Haskell:处理类型和异常

python - 比较类型/类时,使用 "safe"运算符而不是 'is'运算符是不是 '=='?

计数变更程序 - C

Java - instanceof 在应该为真时返回 false

java - Tomcat web项目部署

java - Spring +JPA : object does not get fetched from the database

将 double 或 float 转换为整数类型,哪种类型?

c++ - 同一地址的变量如何产生 2 个不同的值?