为什么会有泛型?
泛型类型是在编译代码时尚不确定到底是什么类型,它可能时String类型,也可能是Integer类型,也可能是自定义类型等等,基于这种不确定性以及多样性,便产生了泛型。在编译时定义了泛型,那么就可以在使用时再决定所需要的参数类型,返回值类型,局部变量类型等等。
泛型的使用
1)在自己写的类右边加上<>,在<>中添加一个大写字母或单词即可,虽然泛型是不确定的,但是由于泛型在被使用的时候会被具体化,所以它其实还是一个与String,Integer等差不多的类。
2)参数/返回值/局部变量等若需始终保持一致,则类型可设为泛型
例如:我们在写MyArray时加上泛型,那么在创建对象时就会具体化这个数组的类型,若是String,那么毫无疑问在add,insert时,肯定添加插入的也必须时String类型,但由于类型是泛型决定的,所以这些方法的参数类型也应该是泛型。
3)泛型不可以实例化对象!!!
4)泛型中也有继承!!!
1)、2)在之前的讲泛型的文章中已做说明,这里重点说明3)、4)
泛型不可实例化
E[] array={};
//报错
E[] array2;
Object[] array3={};
不仅如此,泛型不能实例化是指压根不可以实例化,不可以先如上做声明然后再赋值(这也相当于是实例化)。另外如上的第三种定义属性的形式,定义的类型为Object类型,则其变量在被赋值时,会因为不明其类型而报错。所以就泛型而言,在往其数组中添加东西的时候只能通过方法去实现,在方法的参数中使用泛型,进而实现数组中内容的添加。
泛型中的继承
1>例如,在add方法中,若参数直接为E,则可addE及E的子类对象
2>但参数要是为泛型类及类名+<E>,那么这只可addE类的对象
3> 如果想在2>的情况下添加E的子类,则需要用<? extends E>
4>除了继承,还可以由super变成add父类对象,<? super E>
public class Test<E> {
Object[] arr={};
public void add(E e){
arr[0] =e;
}
public static void main(String[]args) {
Test<A> test1 = new Test<>();
B b=new B();
test1.add(b);
}
}
1>所述如上代码(B是类继承了A类的)
2>所述情况一般是一个数组要加进去一个数组
public class Arr<E> {
Object[] arr={};
public void add(Arr<E> e){
arr[0] =e;
}
public static void main(String[]args) {
Arr<A> arr1 = new Arr<>();
Arr<B> arr2= new Arr<>();
arr1.add(arr2);
//报错
Arr<A> arr3=new Arr<>();
arr1.add(arr3);
//不报错
}
}
假设该数组使用add方法时,加入的是本身类
在创建数组类对象时,选择数组中的数据是A类的,那么它的子类B类的对象就是无法被添加的
public void add(Arr<? extends E> e){
arr[0] =e;
}
public static void main(String[]args) {
Arr<A> arr1 = new Arr<>();
Arr<B> arr2= new Arr<>();
arr1.add(arr2);
//不再报错
Arr<A> arr3=new Arr<>();
arr1.add(arr3);