java泛型程序设计——约束与局限性

【0】README

0.1) 本文描述+源代码均 转自 core java volume 1, 旨在理解 java泛型程序设计 的 约束与局限性 的知识;


【1】 不能用基本类型实例化类型参数

1.1)不能用类型参数代替基本类型, 因此,没有 Pair 只有 Pair;
1.2)其原因是:类型擦除, 擦除之后, Pair类含有 Object类型的域, 而Object 不能存储double 值;


【2】运行时类型查询只适用于原始类型

2.1)虚拟机中的对象总有一个特定的非泛型类型。因此,所有的类型查询只产生原始类型。

  • 2.1.1)如, if( a instanceof Pair) // ERROR , 而 if( a instanceof Pair) // ERROR,
  • 2.1.2)或强制类型转换:
Pair p = (Pair ) a; // warning -- can only test that a is a Pair
  • Attention)要注意这个风险, 无论何时使用instanceof 或涉及泛型类型的强制类型转换表达式都会看到一个编译器警告;
  • 2.1.3)同样的道理, getClass 方法总是返回原始类型, 如 (所以, 推荐用下面的方法来比较两个对象是否是同一个类下的实例)
Pair strPair = ...;
Pair employeePair = ...;
if(strPair.getClass == employeePair.getClass() ) // they are equal == true
  • 它们比较的结果是 true, 这是因为两次调用 getClass 都将返回Pair.class

【3】不能创建参数化类型的数组

3.1)不能实例化参数化类型的数组, 如:

Pair[] table = new Pair[10]; //ERROR
  • 3.1.1)这有什么问题呢? 擦除之后, table 的类型是 Pair[], 把它转换为 Object[]: Object[] objarry =table;
  • 3.1.2)数组会记住他的原始类型: 如果存储其他类型的元素, 就会抛出一个 ArrayStoreException 异常;
objarray[0] = "hello"; // ERROR- component type is Pair not str;
  • 3.1.3)不过对于泛型类型, 擦除会使得这种机制无效。 看以下赋值:
objarray[0] = new Pair(); 能够通过数字存储检查, 不过仍然会导致一个类型错误。  

Conclusion)

  • C1) 综上, 出于以上原因, 不允许创建参数化类型的数组;
  • C2)需要说明的是, 只是不允许创建这些数组, 而声明类型为 Pair[] 的变量是合法的, 不过不能用 new Pair[10] 初始化这个变量而已;
    Annotation)

  • A1)可以声明通配类型的数组, 然后进行类型转换:

Pair[] table = (Pair[])new Pair[10];
  • A2)结果将是不安全的。 如果在 table[0] 中存储一个 Pair《Employee》, 然后 对 table[0].getFirst() 调用一个 String 方法, 会得到一个 ClassCastException 异常;

Hint) 如果需要收集 参数化类型对象,只有一种安全有效的方法:

使用 ArrayList:ArrayList>;

java泛型程序设计——约束与局限性_第1张图片

你可能感兴趣的:(java,泛型,约束与局限性)