p.s.这是萌新自己自学总结的笔记,如果想学习得更透彻的话还是请去看大佬的讲解
目录
泛型概念
泛型,顾名思义,广泛的类型,使用泛型可以帮助我们在一个特定的类、接口或集合、方法中操作不同数据类型的对象。我们可以指定集合中元素的数据类型,也可以使用泛型类来提高代码的复用性。
ArrayList list = new ArrayList<>();
list.add("a");
list.add(12);
list.add("c");
//迭代器遍历
Iterator it = list.iterator();
while (it.hasNext()){
//强制类型转换
String str = (String) it.next();
//多态的弊端是不能范文子类的特有方法
//比如下面这种就会报错
//str.length();
System.out.println(str);
}
泛型类
使用泛型类,我们可以创建具有相同属性、相同构造方法、相同方法的不同数据类型的对象
因此使用泛型类大大提高了代码的复用性
对象的数据类型则是在创建的时候才声明的
格式
修饰符 class 类名称<泛型标识,泛型标识···>{
private 泛型标识 变量名;
······
}
泛型标识可以理解为一种类型形参
常用的泛型标识有T、E、K、V等
package study.fanxing;
public class Test<T> {
private T key;
public Test(T key) {
this.key = key;
}
public T getKey() {
return key;
}
public void setKey(T key) {
this.key = key;
}
@Override
public String toString() {
return "Test{" +
"key=" + key +
'}';
}
}
可以看出泛型标识可以作为数据类、方法返回值、方法形参来使用
泛型接口
泛型接口的定义语法
interface 接口名称<泛型标识、泛型标识······> {
泛型标识 方法名();
······
}
泛型接口的实现类
public interface Generator<T> {
//泛型接口
T getKey();
}
//===========================================
class Apple<E,T> implements Generator<T>{
private T key;
private E value;
public Apple(T key, E value) {
this.key = key;
this.value = value;
}
@Override
public T getKey() {
return key;
}
public E getValue(){
return value;
}
}
//===========================================
class Test2{
public static void main(String[] args) {
Apple<String,Integer> apple = new Apple<>(20,"aa");
System.out.println(apple.getKey());
System.out.println(apple.getValue());
}
}
泛型方法
与泛型类类似,泛型方法是在调用方法的时候才声明了泛型的具体类型
下面这个不是泛型方法,只是一个数据类型为E的成员方法
public E getValue(){
return value;
}
泛型方法的定义语法如下
public <泛型标识、泛型标识······> 返回值类型 方法名(形参列表){
方法体;
}
注意事项
可变参数的泛型方法
public static <E> void print(E... e){
for (int i = 0; i < e.length; i++) {
System.out.println(e[i]);
}
}
当不知道参数的个数时,这种在泛型后面加上...
的泛型方法称为可变参数的泛型方法,即它的参数可以改变
上面的代码为遍历一遍所有形参对应的实参对象
泛型的通配符
泛型的通配符:?
其不仅可以表示不确定的类型,还可以进行类型的限定
其限定方式有两种
<? extends E>
:表示可以传递E或E所有的子类类型(E要明确给出数据类型)
<? super E
>:表示可以传递E或E所有的父类类型(E要明确给出数据类型)