泛型是程序设计语言的一种特性。
泛型的产生:早期的Object类型可以接收任意的对象类型,但是在实际的使用中,会有类型转换的问题。也就存在这隐患,所以Java提供了泛型来解决这个安全问题。
泛型的定义:泛型是一种把明确类型的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,而这种参数类型可以用在类、方法和接口中,分别被称为泛型类
、泛型方法
、泛型接口
泛型的好处 :
- 避免了类型强转的麻烦。
- 它提供了编译期的类型安全,确保在泛型类型(通常为泛型集合)上只能使用正确类型的对象,避免了在运行时出现ClassCastException。
Java泛型中的标记符含义:
E - Element (在集合中使用,因为集合中存放的是元素)
T - Type(Java 类)
K - Key(键)
V - Value(值)
N - Number(数值类型)
U/S - 表示任意类型
? - 表示不确定的java类型
自定义泛型类:
在自定义泛型类的声明,是类名后面加上
在类体中只能对这个泛型进行声明,不能实现或赋值,而且在静态成员都不可以使用泛型
//泛型类
public class A<T> {
//在类上声明的泛型,成员必须是非静态才可以使用
private T name;
public T do1(T ad) {
System.out.println(ad);
return ad;
}
public static void main(String[] args) {
//不写泛型的定义情况下,集合存储比较多元,但是取值容易造成强制转换的问题
A<String> a = new A<String>();
A<Integer> a2 = new A<Integer>();
a.do1("hh");
a2.do1(10);
}
}
泛型方法
public class B {
//泛型方法
//需要在返回值之前加入泛型的声明
//根据你传入的类型来转为对应的Java类型
//静态方法也可以声明泛型,泛型方法可以定义多个.
public static <T> T a(T a){
System.out.println(a);
return a;
}
public static void main(String[] args) {
B b = new B();
b.a("fdf");
b.a(10);
b.a('c');
}
}
泛型边界
public void do1(Class<?> ak){
}
public static void main(String[] args) {
List<Integer> j = new ArrayList<Integer>();
j.add(10);
//extends ,限定通配符的上边界,设置后可以让实例化集合泛型只能取值,无法写入数据
//因为可以确定父类类型,所以可以以父类型去获取数据(向上转型),但是不能写入数据
List<? extends Number> n = j;
//父类可以指向子类
Number a = n.get(0);
//super:限定通配符的下边界,因为确定了子类,但是父不确定,所以下边界就是以子类去存储值
//接收Integer 或者的父类型,因为确定了子类了,所以可以传入值
List<? super Integer> j2= new ArrayList<Number>();
j2.add(50);
//值因为不确定是哪个父类型,所以无法正常取值
System.out.println(j2.get(0));
}