泛型
默认情况下,Collection 集合(如 ArrayList)中的元素可以是任意类型,而取出元素时默认的类型是 Object。
由于多态的约束,取出的元素可能就无法使用自身独有的方法。
如果非要使用,就不得不进行强制类型转换。这样,就会显得比较复杂,而且容易出问题。
泛型: 对容器中的元素数据类型进行约束。
基本语法: <datatype>
示例:
ArrayList<User> users = new ArrayList();
泛型和类型的区别
- 类型:用于约束(指定)外部对象的使用场景。
- 泛型:用于约束(指定)内部对象的使用场景。有时,也称之为类型参数。
- 类型存在多态的使用,而泛型没有多态,是什么泛型,就必须指定对应的元素数据类型。
对于变量 ArrayList users,ArrayList 是类型, 是泛型。
示例
class User {
public void myMethod() {
System.out.println("独有的方法");
}
}
// 自定义数据容器
class MyContainer<E> {
public E data;
}
public class GenericType {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(new User());
list.add("jack");
list.add(new User());
System.out.println(list); // [chapter06_collection.User@3b07d329, jack, chapter06_collection.User@41629346]
Object e = list.get(0); // 取出的元素默认是 Object 类型
// e.myMethod(); // 由于多态的限制,它无法使用 User 的方法
// 这里进行强制类型转换
if (e instanceof User) { // 为了防止出问题,类型转换前,先进行判断。因为集合容器中也有其他类型的数据。
User u = (User) e;
u.myMethod(); // 这样就可以使用它自身独有的方法
}
/*************** 上面的用法就有点麻烦了 **************/
// 为此,我们可以使用泛型,对集合容器存储的数据类型进行约束。
ArrayList<User> users = new ArrayList();
users.add(new User());
users.add(new User());
// 这时,取出的元素类型,就是我们约束的数据类型。
User user = users.get(0);
user.myMethod();
// 自定义容器,使用泛型
MyContainer<User> my = new MyContainer();
my.data = new User();
// 要想使用 MyContainer<User> 的实参,test() 方法的形参就必须是 MyContainer<User>
test(my);
}
public static void test(MyContainer<User> a) {
System.out.println(a);
}
}