泛型(Generic)概念
泛型,JDK1.5新加入的,解决数据类型的安全性问题,其主要原理是在类声明时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这样在类声明或实例化时只要指定好需要的具体的类型即可。
Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。同时,代码更加简洁、健壮。
泛型的声明:1
interface List<T> 和 class TestGen<K,V>
其中,T,K,V不代表值,而是表示类型。这里使用任意字母都可以。常用T表示,是Type的缩写。
泛型的实例化:
一定要在类名后面指定类型参数的值(类型)。如:1
2List<String> strList = new ArrayList<String>();
Iterator<Customer> iterator = customers.iterator();
T只能是类,不能用基本数据类型填充。
泛型的几个重要使用
1.在集合中使用泛型
- 对象实例化时不指定泛型,默认为:Object。
- 泛型不同的引用不能相互赋值。
- 加入集合中的对象类型必须与指定的泛型类型一致。
- 静态方法中不能使用类的泛型。
- 如果泛型类是一个接口或抽象类,则不可创建泛型
- 类的对象。
- 不能在catch中使用泛型
- 从泛型类派生子类,泛型类型需具体化
2.自定义泛型类
1 | class Person<T>{ |
3.泛型方法
方法,也可以被泛型化,不管此时定义在其中的类是不是泛型化的。在泛型方法中可以定义泛型参数,此时,参数的类型就是传入数据的类型。
泛型方法的格式:
[访问权限] <泛型> 返回类型 方法名([泛型标识 参数名称]) 抛出的异常1
2
3
4
5
6
7
8
9public class DAO {
public <E> E get(int id, E e){
E result = null;
return result;
}
}
泛型和继承的关系
如果B是A的一个子类型(子类或者子接口),而G是具有泛型声明的类或接口,G并不是G的子类型!
比如:String是Object的子类,但是List
通配符
1.使用类型通配符:?
比如:List<?> ,Map<?,?>
List<?>是List
2.读取List<?>的对象list中的元素时,永远是安全的,因为不管list的真实类型是什么,它包含的都是Object。
3.写入list中的元素时,不行。因为我们不知道c的元素类型,我们不能向其中添加对象。
唯一的例外是null,它是所有类型的成员。
将任意元素加入到其中不是类型安全的:
Collection<?> c = new ArrayList
c.add(new Object()); // 编译时错误
因为我们不知道c的元素类型,我们不能向其中添加对象。
add方法有类型参数E作为集合的元素类型。我们传给add的任何参数都必须是一个未知类型的子类。因为我们不知道那是什么类型,所以我们无法传任何东西进去。
唯一的例外的是null,它是所有类型的成员。
另一方面,我们可以调用get()方法并使用其返回值。返回值是一个未知的类型,但是我们知道,它总是一个Object
泛型应用
用户在设计类的时候往往会使用类的关联关系,例如,一个人中可以定义一个信息的属性,但是一个人可能有各种各样的信息(如联系方式、基本信息等),所以此信息属性的类型就可以通过泛型进行声明,然后只要设计相应的信息类即可。