为何有泛型
1.泛型是在编译期间进行校验的以保证类型安全。
2.集合不会保证对象的类型,如果不用泛型。那么集合统一用父类object类型来指代,由于java语言的特性,在编译期间,父类和子类都可以用父类来指代,即使在运行期间都是自己的实际类型,集合这个类也是这样的,如果没用用泛型,他们用object这个统一的父类来指代,但是如果在编译期间你要使用子类特有的方法时的话还是要转换成子类类型,现在问题来了,集合类里面什么元素几乎都可以添加,毕竟都是object的子类,但是我们要使用的话,就会出现问题了,我们不知道到底是不是我们要使用的子类,万一集合里面添加了一个不是我们要用的子类,我们转换使用的时候就会报错:java.lang.ClassCastException。
最简单的泛型实例
List
就像这个加了String这个限制,放到集合里面的元素必须是String类型,取出数据的时候也没必要转换为string类型了,因为编译器已经知道了,不需要转换了(额外说下这个多态,多态的原理也正是这个原理,父类可以在编译期间指代子类,但是实际运行还是本身的类型,要是想用子类特有的方法,父类是不行的,虽然确实可以使用,但是编译时不会通过的,会报错,说找不到这个方法。)
自定义泛型接口、泛型类和泛型方法
class Box<T> {
private T data;
public Box() {
}
public Box(T data) {
this.data = data;
}
public T getData() {
return data;
}
}
public class DemoTest {
public static void main(String[] args) {
Box<String> name = new Box<String>("dh");
Box<Integer> age = new Box<Integer>(123);
System.out.println("name class:" + name.getClass()); // com.dh.Box
System.out.println("age class:" + age.getClass()); // com.dh.Box
System.out.println(name.getClass() == age.getClass()); // true
}
}
在这里我们用T来来接收来自外部的参数,泛型终究只是编译期的东西,不会带到运行期,主要就是校验所传信息是否正确罢了,当然在逻辑上我们可以理解这是一些不同类(毕竟一个是String类型,一个是Integer类型),但是实际上这些都是相同的类,就是我们在生成对象的时候,给这个对象传了一个类型参数过去,就是这个类型参数是这个类的一点限制,多了一个参数,一个校验参数罢了。
类型通配符
public class DemoTest {
public static void main(String[] args) {
Box<String> name = new Box<String>("dh");
Box<Integer> age = new Box<Integer>(123);
Box<Number> number = new Box<Number>(456);
getData(name);
getData(age);
getData(number);
get1rData(number); // 1
getUpperNumberData(age); // 2
getUpperNumberData(number); // 3
}
public static void getData(Box<?> data) {
System.out.println("data :" + data.getData());
}
public static void getUpperNumberData(Box<? extends Number> data){
System.out.println("data :" + data.getData());
}
public static void get1rData(Box<? super Number> data) {
System.out.println("data :" + data.getData());
}
}
结果如下:
data :dh
data :123
data :456
data :456
data :123
data :456
我们用?来代替具体的参数类型,主要是为了匹配我们创建类BOX时用了T这个形参。?可以说是所有形参的父类。可以指代任何泛型,是实际参数,不是形参。就是固定好的。
<? extends T>必须是T和T的子类
<? Super T>必须是T或T的父类
从上面的例子可以很容易的看出来。