写在前:
这一篇博客主要来初步的记录以下泛型的相关内容,内容比较琐碎,就不进行目录的整合,后续可能会对泛型这里进行系统性的梳理,此篇博客主要是对泛型有一个简单的认识与理解,需要知晓的内容。
当我调用func()的时候,进行传递的是一个真实的数据,是一个数值,在有些情况下,我们会想传递一个数据类型过去。
《Java编程思想》对泛型的介绍:一般的类和方法,只能使用具体的类型:要么是基本类型,要么是自定义类。如果要编写可以应用于多种类型的代码,这种刻板的限制就会对代码的舒服很大。
泛型是在JDK1.5引入的新的语法,通俗讲,泛型就是适用于许多许多类型,从代码上讲,就是对类型实现了参数化。
思考:现在需要我们实现一个类,这个类里面有一个数组,将数组实现成通用的【什么类型的数据都可以存放】,也可以根据方法成员返回数组中的某个下标的值。
我们可以编写出以下的代码:
class MyArray1{public Object[] obj = new Object[3];//讲数组定义为Object数组,长度为3,不放数据//提供一个方法,getPos,给一个pos下标,就可以返回pos下标对应的值。public Object getPos(int pos){return obj[pos];}public void setObj(int pos,Object val){obj[pos] = val;}
}
public class Test2 {public static void main(String[] args) {MyArray1 myArray1 = new MyArray1();myArray1.setObj(0,10);myArray1.setObj(2,"hello");myArray1.setObj(3,10.0);double d = (double)myArray1.getPos(3);}
}
但是我们发现,这样的方法并不是通用的:
解决第一个问题:存储数据的时候,什么数据都可存储?
可以在这里加上一个<T>,代表的含义是当前类是一个泛型类。
每次进行获取数据的时候都要进行类型的转换
把类型作为参数进行传递。
1.存储数据的时候,可以帮我们进行自动的类型检查。
2.获取元素的时候,可以帮我们进行类型转换。
以上两步都是在编译的时候,泛型是编译时期的一种机制,在运行的时候没有泛型的概念。
规定:泛型当中,不能去实例化一个泛型类型的数组。
小结:
1.泛型是将数据类型参数化,进行传递。
2.使用<T>表示当前类是一个泛型类。
3.泛型目前为止的优点:数据类型参数化,编译时自动进行类型检查和转换。
规定:泛型当中不能去实例化一个泛型类型的数组。
裸类型:裸类型是一个泛型类没有带着类型实参,例如MyArrayList就是一个裸类型。
问题:Java到底如何进行编译的?
擦除机制!!
泛型的上界【泛型无下界】
在定义泛型类的时候,有时候需要对传入的类型变量做一定的约束,可以通过类型边界来约束。
观察以上的代码为什么会报错?
我们使用泛型来进行一个数组中最大值的查找,这里出现了报错,具体原因是因为这里的E类型是一个引用类型,所以就不可以通过大于小于号进行比较,引用类型是通过compare方法来进行比较的。
但是这里并没有相关的方法,原因是因为
没有实现接口。:E类型被擦除为Object,Object没有实现对应的接口。
这时就需要我们对E类型进行给《边界》,如果不给边界最终就会被擦除为Object
在这里,<E extends N>这个就叫做泛型的上界,代表将来指定的参数类型一定是实现了这个接口的。
<E extends Number> 代表:E是Number的子类或者是Number本身。
创建一个新的类A,继承Number,此时,就可以确定使用Number的子类,确定泛型的上界。
需要重点注意的内容是泛型有上界,但是泛型是没有下界的。
以上是泛型类,那么是否存在泛型方法?
泛型静态方法: