泛型(eclipse)
泛型的定义
通常来讲,我们创建一个List集合,什么东西都是可以在里面放的,char也好,int也好,乱七八糟,我们这是常常会看到eclipse的左面显示着黄色的警告,虽然程序员不关心警告,但是去掉警告多少会舒心不是?
泛型,在jdk1.5加入,其主要原理是在类声明时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这样在类声明或实例化时只要指定好需要的具体的类型即可。
List<Integer> list = new ArrayList<Integer>();
list.add(1);
这里指定泛型为Integer,这样如果我们使用list的添加方法,就只能添加int的数据类型,否则会报编译错误
当然了,<>里面并不是只能添加数据类型,对象也来者不拒
泛型方法的格式:
- [访问权限] <泛型> 返回类型 方法名([泛型标识 参数名称]) 抛出的异常
其实这里的抛出异常可以不写,如果不需要的话
泛型与继承
// 泛型和继承的关系
class A<T> {
protected T t;
public T getT() {
return t;
}
}
class B1 extends A {} // 子类无视泛型 , 导致泛型类型永远是Object, 类型模糊
class B2 extends A<String> {} // 子类直接把泛型父类的泛型类写死, 子类中继承的T类型永远是固定的
class B3 extends A<Boolean> {}
class C<T> extends A<T> {} // 子类也泛型, 在子类对象创建时再动态决定泛型类型, 这是最灵活的做法.
注意
String是object的子类,但是泛型为String类型的List不是泛型为Object的List的子类
使用类型通配符:?
?是一个模糊类型,因此我们可以认为?比object包含的范围更大
比如List<?>是List< Object>或List< String>的父类
当然有一个例外
List<?> list = new ArrayList<String>();
list.add(null);
//list.add("ad");//编译错误
list.get(0);
在这里添加null不报错是因为null是一个例外,这个null是所有类型的成员
而我们不知道修饰list的泛型是什么,所以会报错
我们可以调用get方法返回这个未知的数,假设我们忘了刚才添加的东西
那么get方法肯定有效,因为我们知道他总会返回一个Object类型
public static void main(String[] args) {
List<?> list = null;
list = new ArrayList<String>();
list = new ArrayList<Double>();
// list.add(3);
list.add(null);
List<String> l1 = new ArrayList<String>();
List<Integer> l2 = new ArrayList<Integer>();
l1.add("尚硅谷");
l2.add(15);
read(l1);
read(l2);
}
static void read(List<?> list) {
for (Object o : list) {
System.out.println(o);
}
}
泛型类使用
我们使对象实例化之后不定义泛型的时候,默认为object
加入集合里的类型必须与指定的泛型一致
指定泛型为Integer就只能加入int类型的数据,否则会编译出错
泛型类可以派生子类病具体化
如泛型为object的类的子类可以泛型是integer
class T<Oject>{ }
class A extends T<Integer>{ }
反过来就不可以了,就好比你爸是百万富翁,你可以继承百万财产,也可以继承十万财产,这个随你喜欢
但是你爸现在手里只有十块钱,那你总不可以对你爸说你要继承一百万财产,这个肯定不行的,除非你去抢银行
不能在catch中使用泛型
try {
} catch (Exception e) {
List<Integer> list2 = new ArrayList<Integer>();
list2.add(1);
System.out.println(list2);
}
这个例子看到了么,catch通过了,但是很遗憾这个并不是泛型
我刚开始也是不明白泛型的区别,于是我们来斟酌这个词的意思好了,泛型是一种广泛的类型,也就是这个泛型写在那里,我们也不知道会什么类型,只有实例化的时候才会考虑到用什么类型来接收数据,在这之前,就让这个类型模糊化好了