定义类、接口、方法时,同时声明了一个或者多个类型变量(如:
public class Main {
public static void main(String[] args) {
ArrayList list = new ArrayList<>();//规定了必须是String类型
list.add("hi~");
list.add("hello~");
for (int i=0;i
作用:提供了在编译阶段约束能操作的数据类型并自动进行检查的能力,这样可以避免强制类型转换及其可以出现的异常。
本质:把具体的数据类型作为参数传给类型变量
MyArrayList.java
public class MyArrayList {
private Object[] arr = new Object[10];
private int size;
public boolean add(E e){
arr[size++] = e;
return true;
}
public E get(int index){
return (E) arr[index];
}
}
Main.java
public class Main {
public static void main(String[] args) {
//规定了只能接收String类型的
MyArrayList list = new MyArrayList<>();
list.add("java1");
list.add("java2");
String ele = list.get(1);
System.out.println(ele);
}
}
//输出结果
//java1
可以设定多个参数类型,如
public class MyClass {
public void put(E e,T t){
...
}
}
也可以实现泛型数据类型的继承
此时规定的数据类型必须是继承Animal类的类或者就是Animal类
public class MyClass2 {
...
}
泛型接口
public interface Data {
void add(T t);
ArrayList getByName(String name);
}
实现类实现接口
mac快捷键【control+回车】
public class TeacherData implements Data{
@Override
public void add(Teacher teacher) {
}
@Override
public ArrayList getByName(String name) {
return null;
}
}
同理也可以实现继承
public class Test {
public static void main(String[] args) {
//此时T为String类型
System.out.println(test("java"));
//此时的T为Dog类型
Dog d = test(new Dog());
System.out.println(d);
}
public static T test(T t){
return t;
}
}
具体示例如下
public class Test {
public static void main(String[] args) {
//创建一个宝马车的ArrayList对象(BMW类继承于Car类)
ArrayList bmws = new ArrayList<>();
bmws.add(new BMW());
bmws.add(new BMW());
go(bmws);
//创建一个奔驰车的ArrayList对象(BENZ类继承于Car类)
ArrayList benz = new ArrayList<>();
benz.add(new BENZ());
benz.add(new BENZ());
go(benz);
}
//第一种方法
public static void go(ArrayList cars){
}
//第二种方法
//?代表通配符,在使用泛型时代表一切类型
//public static void go(ArrayList extends Car> cars){
//}
}
泛型上限:? extends Car(上限):?只能是Car或者是Car的子类
泛型下限:? super Car(下限):?只能是Car或者是Car的父类
- 泛型是工作在编译阶段的,一旦程序编译成class文件,class文件中就不存在泛型了,这就是泛型擦除。
- 泛型不支持基本数据类型,只能支持对象类型(引用数据类型)。