lt;数据结构与算法分析gt;读书笔记--利用Java5泛型实现泛型构(2)
示例七: InstanceOfCheckExample { main(String[] args) { GenericMemoryCell<Integer> celll = (); celll.write(4); Object cell = celll; GenericMemoryCell<String> cell2 = (GenericMemoryCell<String>) cell; String s = cell2.read(); } } ? 这里的类型转换在运行时是成功的,因为所有的类型都是GenericMemoryCell。但在最后一行,由于对read的调用企图返回一个String对象从而产生一个运行时错误。 结果,类型转换将产生一个警告,而对应的instanceof检测是非法的。 ? 3.static的语境在一个泛型类中,static方法和static域均不可引用类的类型变量,因为在类型擦除后类型变量就不存在了。另外,由于实际上只存在一个原始类,因此static域在该类的诸泛型实例之间是共享的。 4.泛型类型实例化不能创建一个泛型类型的实例。如果T是一个类型变量 T obj = new T(); 则语句是非法的。T由它的限界代替,这可能是Object或抽象类,因此对new的调用没有意义。 5.泛型数组对象也不能创建一个泛型数组。如果T是一个类型变量 T[] arr = new T[10]; 则语句是非法的。T将由它的限界代替,这可能是Object T,于是(由类型擦除产生的)对T[]的类型转换将无法进行,因为Object[] IS-NOT-A T[]。由于我们不能创建泛型对象的数组,因此一般说来我们必须创建一个擦除类型的数组,然后使用类型转换。这种类型转换将产生一个关于未检验的类型转换的编译警告。 ? 6.参数化类型的数组参数化类型的数组的实例化是非法的。 GenericMemoryCell<String> [] arr1 = new GenericMemoryCell<>[10]; GenericMemoryCell<Double> cell = (); cell.write(4.5); Object[] arr2 = arr1; arr2[0] = cell; String s = arr1[0].read(); 正常情况下,我们认为第四行的赋值会生成一个ArrayStoreException,因为赋值的类型有错误。可是,在类型擦除之后,数组的类型为GenericMemoryCell[],而加到数组中的对象也是GenericMemoryCell,因此不存在ArrayStoreException异常。于是,该段代码没有类型转换,它最终将在第五行产生一个ClassCastException异常,这正是泛型应该避免的情况。 ? 示例代码已经上传到我的Github:https://github.com/youcong1996/The-Data-structures-and-algorithms/tree/master/Introduction ? (编辑:ASP站长网) |