Java泛型

[size=small]泛型是JAVA SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

在JAVA SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。

泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。

泛型在使用中还有一些规则和限制:
1、泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。
2、同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。
3、泛型的类型参数可以有多个。
4、泛型的参数类型可以使用extends语句,例如<T extends superclass>。习惯上成为“有界类型”。
5、泛型的参数类型还可以是通配符类型。例如Class<?> classType = Class.forName(java.lang.String);

以下是对泛型的几点总结:
1. 泛型在Collections(或使用泛型类型参数声明的其他类和方法)上强加编译时类型安全;
2. 一个ArrayList<Animal>能够接受类型为Dog、Cat或任何其他的Animal子类型(子类,或者如果Animal是一个接口,则为实现)的引用;
3. 当使用泛型集合时,从集合获取(所声明的类型的)元素不需要进行强制转换。而使用非泛型集合时,强制转换是要求的:
List<String> gList = new ArrayList<String>();
List list = new ArrayList();

String s = gList.get(0);
String s = (String)list.get(0);
4. 可以将泛型集合传递到带有非泛型集合的方法,但结果可能非常糟糕。编译器不能阻止方法将错误的类型插入到以前是类型安全的集合;
5. 如果编译器能够认识到,非类型安全的代码可能会危害原来声明为类型安全的东西,就会给出一个编译器警告。例如,如果将一个List<String>传递到声明为void foo(List aList){aList.add(aninteger);}的方法,则会得到一个警告,因为add()有可能是“不安全的”。
6. “编译不带错误”与“编译不带警告”是不相同的。编译时的警告不被认为是一个编译错误或失败;
7. 泛型类型信息在运行时不存在——它只用于编译时安全。混合泛型与遗留代码所得到的编译后代码,在运行时可能抛出异常;
8. 多态赋值只适合于基本类型,而不是泛型类型参数。可以这样编写代码:
List<Animal> aList = new ArrayList<Animal>();
不能这样编写代码:
List<Animal> aList = new ArrayList<Dog>();
9. 多态赋值规则适合于能够进行赋值的任何地方。如下的代码是不允许的:
void foo(List<Animal> aList){} // 不能传递一个List<Dog>
List<Animal> bar(){} // 不能返回一个List<Dog>
10. 通配符语法允许泛型方法,接受方法参数所声明的类型的子类型(或超类型):
void addD(List<Dog> d){} // 只能传递<Dog>
void addD(List<? extends Dog>){} // 可以传递<Dog>或<Beagle>
11. 通配符关键字extends用于表示“扩展”或“实现”。因此,在<? extends Dog>中,Dog可以是一个类,也可以是一个接口;
12. 当使用通配符时,List<? extends Dog>表示可以访问集合但不能修改它;
13. 当使用通配符时,List<?>表示任何泛型类型都可以赋给引用,但只能访问,不能修改;
14. List<Object>只引用一个List<Object>,而List<?>或List<? extends Object>能保存任何类型的对象,但只能访问;
15. 泛型的声明约定用T代表类型,用E代表元素:
public interface List<E>
boolean add(E o)
16. 泛型类型标识符可以用在类、方法和变量声明中:
class Foo<T>{} // 类
T anInstance; // 实例变量
Foo(T aRef){} // 构造函数的参数
void bar(T aRef){} // 方法参数
T baz(){} // 返回类型
编译会将它们替换成实际的类型。
17. 可以在一个声明中使用多个参数化类型:
public class UseTwo<T, X>{}
18. 可以使用不在类中定义的类型声明泛型方法:
public <T> void makeList(T t){}
没有将T用作返回类型。这个方法有一个void返回类型,但是为了在方法的参数中使用T,就必须在返回类型前声明<T>。[/size]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值