泛型
泛型是一种参数化类型的机制,它允许我们在定义类、接口或方法时使用一个或多个类型参数来代替具体的类型。通过使用泛型,我们可以编写更加通用和类型安全的代码。
泛型的主要优点是提高了代码的重用性和可读性,并且在编译时提供了类型检查。使用泛型可以避免类型转换的麻烦,并减少了运行时错误的可能性。
注意事项
1)泛型只能指代引用类型,不能指代基本数据类型。
2)在给泛型指定基本类型后,可以传入该类型或者其子类类型。
3)在集合List中,如果不指定数据类型则默认为Object类型。
4)一般使用单个大写字母来指代泛型。
5)使用自定义泛型数组时不能初始化(因为类型未确定)。
泛型类
当我们在Java中定义一个泛型类时,我们使用尖括号(<>)来指定一个或多个类型参数。
泛型类示例:
public class Box<T> {
private T item;
public void setItem(T item) {
this.item = item;
}
public T getItem() {
return item;
}
}
在上面的代码中,我们定义了一个泛型类Box,其中T表示类型参数。通过使用泛型,我们可以在实例化Box类时指定具体的类型参数。例如:
Box<Integer> box = new Box<>();
box.setItem(10);
int item = box.getItem(); // 可以直接获取到整数类型的值,无需进行类型转换
泛型接口
泛型接口示例:
public interface List<T> {
void add(T item);
T get(int index);
}
在上面的代码中,我们定义了一个泛型接口List,其中T表示类型参数。通过使用泛型接口,我们可以在实现类中指定具体的类型参数。例如:
public class ArrayList<T> implements List<T> {
private T[] array;
public void add(T item) {
// 添加元素的具体实现
}
public T get(int index) {
// 获取元素的具体实现
}
}
泛型方法
泛型方法示例:
public static void main(String[] args) {
aaa<String> aaa = new aaa<>();
aaa.printClass("lxg",12345);
}
public static class aaa<T>{
public <E> void printClass(T t,E e){
System.out.println(t.getClass());
System.out.println(e.getClass());
}
}
输出:class java.lang.String
class java.lang.Integer
在普通泛型方法中可以使用类的泛型,但在静态方法中不能使用类的泛型。
泛型的通配符
<?> : 支持任意泛型类型。 <? extends A>:支持A类以及A类的子类,规定了泛型的上限。 <? super A>:支持A类以及A类的父类,不限于直接父类,规定了泛型的下限。
public class Test1 {
public static void main(String[] args) {
ArrayList<God> gods = new ArrayList<>();
ArrayList<Animal> animals = new ArrayList<>();
ArrayList<Cat> cats = new ArrayList<>();
test1(animals); // 可以传入任意类型
test2(cats); // 只能传入animal或其子类型
test3(gods); // 只能传入animal或其父类型
}
public static void test1(List<?> list){
System.out.println(list);
}
public static void test2(List<? extends Animal> list){
System.out.println(list);
}
public static void test3(List<? super Animal> list){
System.out.println(list);
}
}
class God{}
class Animal extends God{}
class Cat extends Animal{}