java 范型 约束

 转自:

 

http://www.myexception.cn/mobile/692129.html

向作者致谢!

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

大多数这些需要注意的问题,都是由类型擦除引起的。

一、基本类型

不能用类型参数替换基本类型。就比如,没有ArrayList<double>,只有ArrayList<Double>。因为当类型擦除后,ArrayList的原始类型变为Object,但是Object类型不能存储double值,只能引用Double的值。

 

二、运行时类型查新

举个例子:

 

Java代码 复制代码 收藏代码
  1. ArrayList<String> arrayList=new ArrayList<String>();
ArrayList<String> arrayList=new ArrayList<String>();

因为类型擦除之后,ArrayList<String>只剩下原始类型,泛型信息String不存在了。

 

那么,运行时进行类型查询的时候使用下面的方法是错误的

 

Java代码 复制代码 收藏代码
  1. if( arrayList instanceof ArrayList<String>)
if( arrayList instanceof ArrayList<String>)

java限定了这种类型查询的方式

 

 

Java代码 复制代码 收藏代码
  1. if( arrayList instanceof ArrayList<?>)
if( arrayList instanceof ArrayList<?>)


 

三、异常

1、不能抛出也不能捕获泛型类的对象。事实上,泛型类扩展Throwable都不合法。例如:下面的定义将不会通过编译:

 

Java代码 复制代码 收藏代码
  1. public class Problem<T> extends Exception{......}
public class Problem<T> extends Exception{......}

为什么不能扩展Throwable,因为异常都是在运行时捕获和抛出的,而在编译的时候,泛型信息全都会被擦除掉,那么,假设上面的编译可行,那么,在看下面的定义:

 

 

Java代码 复制代码 收藏代码
  1. try{
  2. }catch(Problem<Integer> e1){
  3. 。。
  4. }catch(Problem<Number> e2){
  5. ...
  6. }
try{
}catch(Problem<Integer> e1){
。。
}catch(Problem<Number> e2){
...
} 

类型信息被擦除后,那么两个地方的catch都变为原始类型Object,那么也就是说,这两个地方的catch变的一模一样,就相当于下面的这样

 

 

Java代码 复制代码 收藏代码
  1. try{
  2. }catch(Problem<Object> e1){
  3. 。。
  4. }catch(Problem<Object> e2){
  5. ...
try{
}catch(Problem<Object> e1){
。。
}catch(Problem<Object> e2){
...

这个当然就是不行的。就好比,catch两个一模一样的普通异常,不能通过编译一样:

 

 

Java代码 复制代码 收藏代码
  1. try{
  2. }catch(Exception e1){
  3. 。。
  4. }catch(Exception e2){//编译错误
  5. ...  
try{
}catch(Exception e1){
。。
}catch(Exception  e2){//编译错误
...

 

你可能感兴趣的:(java)