目录
自定义泛型:(在自定义泛型中:泛型是可以去接收数据类型的一种引用变量)
自定义泛型:(在自定义泛型中:泛型是可以去接收数据类型的一种引用变量)
泛型和类:
Clsss Person<E>{
E name;//name属性的类型为E
public E sort(){}//返回类型为E
public void swop(E num){}//传入一个E类型的参数
}
new Person<Integer>();
//不难看出其实自定义泛型指的是替换的作用。
注意:在实例化对象的时候,如果你的自定义类有自定义泛型E,不是一定要传入泛型的类型的,如果你不传入泛型的类型,那么你这个E就默认为Object
指定泛型
指定泛型一般在集合和接口中使用到,比如:
ArrayList list = new ArrayList(); 他其实里面也有泛型,他等价于
ArrayList<Object> list = new ArrayList()<>; 也就是说他可以传入任何类型对象。
这个传入的对象最后进到它的底层会把里面的E换掉,如下举例源码:
//一定要看懂上面这张图对应视频是P561
在接口中使用泛型
注意:在接口中的所有普通属性都是属于静态的,所以 比如这样:
在你实现这个接口后调用comparaTo这个方法的时候表示你可以传入一个T类型的对象,这个T默认是Object。现在我有一个类实现了这个接口
并且指定了他的T为MyDate,那么你在调用ComparatorTo方法的时候这个就只能传入一个MyDate对象了。
在普通类中定义泛型方法
在泛型类中定义泛型方法
//在你把参数传进去的时候它会自动判断你的T和R是啥类型,这里面T是String,R是Interge(自动装箱)
//注意最后的hi方法她不是泛型方法,因为只是使用了类的泛型。不要和上面的eat方法混淆了
泛型通配符的使用
第一个不正确,你在定义List的泛型为Object的时候,就已经确定了你需要创建对象的泛型。也就是说你的运行类型的泛型必须和编译类型的泛型保持一致。
通配符的三种使用方式:
后面两种上限还是下限你就这样看,比如 ? extends AA 直接从后面往前看,我可以接受AA或者?,?继承AA就表示这个?是AA的子类。所以就是我可以接受AA或者AA的子类。别管上下限
注意这三种返回时中前面都是带有一个List的,也就是说你首先必须得是List,至于你这个List中的List<这里面是啥泛型类型上面有些限制>