今天主要来认识泛型~
什么是泛型呢?
泛型是从什么时候有的呢?
首先,泛型并不是从Java的开始就存在的,而是在Java1.5版本中引入的。
接下来我们来具体看一下泛型是什么。我们以冒泡排序为例,在对数据进行排序时,数据类型是不同的,有double[ ] sort、int[ ] sort等等......如果对每种数据类型都写相应的算法,可以实现但是工程量太大。
因此,引入了泛型。
泛型不讨论基本数据类型,只讨论引用数据类型(对象)。
引用是有上下级关系的,比如:
class A extends B{...} 我们就可以认为B是A的上级
class A extends C{...} 我们就可以认为C是A的上级
如果b=a;那么b类型是a类型的上级
如果c=a;那么c类型是a类型的上级 //向上转型是自然的
Java中的Object类,是顶级类型,是所有类型的上级。
Object o=一切引用;
在没有泛型之前,Java解决多种不同类型的冒泡排序问题是通过Object来解决的(只针对引用类型)。
但是使用Object是存在一些矛盾的。比如:
//编写代码的人希望数组中放的是Student对象
Object o={....};
o1=Student 对象;//符合预期,并且代码没有语法错误
//其他编写代码的人不知道这个规则
o2=Teacher 对象;//不符合预期,但是代码没有语法错误
由此可见,使用Object无法从语法层面将不符合预期的赋值在初期暴露出来。
因此,再次强调引入泛型的必要性。
泛型(Generic Type)把类型变量化。底层原理是引用的向上转型是自然的。
基本数据类型是无法使用泛型的(将基本类型一一对应一个包装类型来解决的)。
关于泛型我们需要掌握以下几点:
1.实现带有泛型能力的方法(泛型方法的定义);
2.泛型方法的使用;
3.定义一个带有泛型的类/接口
4.泛型类/接口的使用
5.泛型的特殊规则
//返回值类型前面的:定义了一个类 类型变量E
public static void sort(E[] array){
}
//泛型方法的使用
public static void test(){
Random[] array =new Random[10];
//标准写法
BubbleSort.sort(array);//指定了变化的数组类型时Random
//省略写法
BubbleSort.sort(array);
}
//定义泛型方法(接口同理)
public class GenericClass{
T1 a;
T2 b;
T3 c;
}
在新建对象的时候才创建T1,T2,T3的类型。
public class UseGenericClass {
public static void main(String[] args) {
//Random,String,Scanner
//完整写法
//引用上通过<>体现类型
//new对象时,类名后面要体现类型
GenericClass r;
r=new GenericClass();
GenericClass s=new GenericClass();
//常见写法
//new的时候类型可以省略但是<>不能省略
GenericClass t=new GenericClass<>();
}
}
在源码中有泛型->经过编译器编译->字节码文件(类文件)(泛型消失)->虚拟机
以上过程就是泛型的擦除。
a.擦除的时候,擦到类型的上限:
class GenericClass{
//T的上限是A
T t;//编译完成后,是A t;
}
new GenericClass();
new GenericClass();//B是A的下级(B是A的子类,B是A的实现类)
new GenericClass();//C和A没有关系,或者C是A的上级,则无法通过
class GenericClass等价于 GenericClass();
即擦除成它的上限。
b.使用时可以使用通配符
void func(GenericClass> c){
}
?表示可以填充任意值。
完整的尖括号是泛型的标志。
对lambda表达式:
interface A{
void func(String s);
}
void tset(A a){...}
//标准写法
class B implements A{...}
B b=new B();
test(b);
//尤其是只用一次的情况下。以上写法太啰嗦
//因此,引入匿名对象(适合只用一次的对象)
test(new A(){...}); //定义一个A的子类没有名字,同时实例化一个对象
//如果接口中只有一个方法(或者只有一个方法需要重写),可以使用lambda表达式
test((String x)->{...});
(String x)->{...}//->是lambda 表达式的标志