本文章是个人学习笔记,如有错误欢迎指正
Java泛型
一、定义和存在意义
定义:允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明,实质是:参数化类型
好处:
- 类型安全
- 消除强制类型转换
二、泛型类、接口
泛型类定义:
/**
* 泛型类定义
* @param <T> 泛型标识---类型形参,T在创建对象的时候指定具体的数据类型,
* 由外部使用类来指定
*/
public class Generic<T> {
private T key;
public Generic(T key) {
this.key = key;
}
public T getKey() {
return key;
}
public void setKey(T key) {
this.key = key;
}
}
泛型类使用:
Generic<String> stringGeneric=new Generic<>("泛型实参");
注意:
- 若泛型类在创建对象时候没有指定类型,将视为object类型
- 泛型类不支持基本数据类型,如int,必须使用Integer来指定
- 同一泛型类根据不同数据类型创建的对象本质上是同一类型,getClass()相等,所以没法进行方法重载
从泛型类派生子类:
-
父类是泛型类,子类也是,则要求子类和父类的泛型类型要一致,若继承时父类不指定,则默认Object类
//父类 public class Parent<E> { private E key; public E getKey() { return key; } public void setKey(E key) { this.key = key; } } //第一种继承方式: class Child<T> extends Parent{ @Override public Object getKey() { return super.getKey(); } } //第二种继承方式: class Child2<T> extends Parent<T>{ @Override public T getKey() { return super.getKey(); } }
-
父类是泛型,子类不是,则要求父类必须明确泛型的数据类型,或者不指定默认Object
public class Parent<E> { private E key; public E getKey() { return key; } public void setKey(E key) { this.key = key; } } class Child3 extends Parent{ @Override public Object getKey() { return super.getKey(); } } class Child4 extends Parent<String>{ @Override public String getKey() { return super.getKey(); } } //编译出错 class Child5 extends Parent<T>{ @Override public Object getKey() { return super.getKey(); } }
泛型接口定义:
public interface GenericInterface<T> {
T getKey();
}
泛型接口的使用:
-
实现接口的类是泛型类,则要求泛型类型一致
public interface GenericInterface<T> { T getKey(); } class Apple<T>implements GenericInterface<T>{ @Override public T getKey() { return null; } }
-
实现接口的类不是泛型类,则要求明确泛型的数据类型
public interface GenericInterface<T> { T getKey(); } class Organe implements GenericInterface<Integer>{ @Override public Integer getKey() { return null; } }
泛型方法:
//例如:
public <E> E get(ArrayList<E> list){
return list.get(5);
}
注:泛型方法也支持静态方法
二|类型通配符
类型通配符使用?代替类型实参,而不是形参
比如
定义泛型类:
class Box<T>{
......
}
定义泛型方法:
注意:泛型类是无法进行泛型重载的
//编译错误
public void showBox(Box<String> box){
......
}
public void showBox(Box<Integer> box){
......
}
正确定义:
public void showBox(Box<?> box){
......
}
使用
Box<Integer> b1=new Box();
Box<String> b2=new Box();
showBox(b1);
showBox(b1);
类型通配符的上下限:
上限
//表明该泛型的类型只能是该实参类型,或者是该实参的子类类型
类/接口<? extends 实参类型>
下限
//表明该泛型的类型只能是该实参类型,或者是该实参的父类类型
类/接口<? super 实参类型>
三、类型擦除
泛型是jdk1.5引入的,但是泛型可以兼容之前的代码是由于:泛型只存在代码编译阶段,在进入jvm之前就已经将泛型相关信息擦除了。
无限制类型擦除:对于无限制的泛型类型都将默认视为Object类型
有限制类型擦除:对于有上限的泛型类型,将擦除为上限的类型
-
桥接方法:对于泛型接口中的泛型类型都会默认视为Object类型,在其实现类中,会生成一个有指定类型的实现方法和一个Object类型的实现方法来保持类与接口的实现关系
擦除之前:
interface Box<T>{ T get(T key); } class BoxImpl implements Box<Integer>{ @Override public Integer get(Integer key) { return key; } }
擦除之后:
interface Box{ Object get(); } class BoxImpl implements Box{ public Integer get(Integer key) { return key; } @override public Object get(Object key) { return get((Integer) key); } }