泛型的特点
使用泛型的规则
- 泛型可以使用在返回类型和参数类型上面
比如:public T fun(T t) {}
- 泛型可以使用在成员变量上面和类型上面
比如:classA {
private T bean;
}
- 泛型可以使用在局部变量上面
比如:publicvoid fun2() {
T b = …..;
}
- 泛型不可以new
比如:new T();//不行的!
- 在创建泛型类实例时,需要为其类型变量赋值
比如:Aa = new A();
-
如果创建实例时,不给类型变量赋值,那么会有一个警告!
6.泛型方法与泛型类没什么关系,泛型方法不一定非要在泛型类中
泛型的继承和实现
1.规则:
子类不是泛型类:需要给父类传递类型常量
比如:class AA extends A<String> {},这个时候AA不是泛型类,而A是泛型类,这个时候需要指定子类中泛型的类型常量,这个时候父类中所有的T都会被String替换
子类是泛型类:可以给父类传递类型常量,也可以传递类型变量
比如:class AA3<E> extends A<E> {}
class AA3<E> extends A<String> {}
泛型的局限性
就拿集合来说:
List<String>list = new ArrayList<String>();
//List<Object>list2 = new ArrayList<String>();
局限性1:
集合等号两边所传递的值必须相同否则会报错,原因就是Java中的泛型有一个擦除的机制,就是所编译器期间编译器认识泛型,但是在运行期间Java虚拟机就不认识泛型了,有兴趣的可以通过反编译来看一下,那么运行期间就会变成Listlist = new ArrayList ();如果最终变成这个样子了,那么传入泛型还有什么意思,所以在程序编译期间就报错,这样泛型就得以应用了(这个实际上是引用c++中的模板没有用好才导致的,Java中用泛型的场景就是写一个通用的方法)。
局限性2:
现在要写一个比较通用的方法。
publicvoid fun1(List<Object> list){
System.out.println("泛型方法");
}
但是在调用的时候传入的String类型变量就会报错
publicvoid test2(){
List<String>list = new ArrayList<String>();
//fun1(list);报错
}
原因无他,就是泛型擦除,理由同局限性1,那么怎么办呢?
重载吧!类型变量为String的一个,Integer的一个。
public void fun1(List<String> list){
System.out.println("泛型方法1");
}
public void fun1(List<Integer>list){
System.out.println("泛型方法2");
}
这个时候编译器又报错了,为啥呢?还是泛型擦除,当运行的时候会导致,参数都变成List list,那么这两个方法都变成一个了。,这,我晕,会不会觉得,泛型好垃圾。别急,接下来人家Java才不傻,给你提供了另一种方法,就是通配符。
一、什么是泛型?
通过泛型可以定义类型安全类,而不会损害类型安全、性能或工作效率
二、泛型的好处
1、一次性的开发、测试和部署代码,通过任何类型来重用它
2、编译器支持和类型安全
3、不会强行对值类型进行装箱和取消装箱,或者对引用类型进行向下强制类型转换,所以性能得到显著提高。
4 、封装一些共性问题,可以简化很多代码,使代码更加有层次,简单
5、比object类范围明显缩小了,提高了程序运行的效率