1.什么是泛型泛型是在JDK1.5引入的新的语法通俗讲泛型就是适用于许多许多类型。从代码上讲就是对类型实现了参数化。看到标红的这句话有些兄弟可能会有疑惑我们以前传参传得是一个整形数据传得是一个引用我从来没传过类型嘛类型难道还能作为参数传递对没错接下来我们就来看一下类型作为参数传递的实现方式2.引出泛型我们以前学过继承和多态我们知道所有类的父类默认是Object类我们现在目标是数组中可以存放任何类型的数据这时候我们就可以new一个Object类型的数组12345678910111213141516classMyArray {publicObject[] array newObject[10];publicObject getPos(intpos) {returnarray[pos];}publicvoidsetPos(intpos, Object value) {array[pos] value;}}publicclassTestDemo {publicstaticvoidmain(String[] args) {MyArray myArray newMyArray();myArray.setPos(0,1);myArray.setPos(1,hello);}}当我们写出这样一个代码的时候我们发现数组中什么元素都能放了可以放整形数据可以放字符串还可以放小数这里面能放的东西太多了你能知道某个下标的元素是什么样的类型吗当我们取元素的时候会发现你的代码编译都不能通过为什么会出现这样的情况呢我相信大部分兄弟们都知道我们观察getPos的返回值是Object也就意味着我们拿出来的可能是任意元素但编译器知道吗它只知道返回的是一个Object这就很明显了父类给子类这不纯纯的向下转型吗向下转型就必须要强转类型否则你的代码就不可能通过。那么问题又来了我这里只是放了两个元素肉眼还能看的过来但是这里面的类型时刻在发生改变就算你知道类型你每次都需要强转吗我是动态的啊我代码是写死的啊所以这个地方如果用Object去做的话会显得格外麻烦而且局限性非常的大我们现在的困境有两个1.任何类型都可以放不好控制2.每次取元素的时候都得进行强制类型转换这时候我们得搞一手希望工程我们的希望是1.我们能不能自己指定类型2.我们能不能不再进行类型转换呀能不能把这一步省略呀兄弟为了解决这一问题我们java就引入了这个东西----》泛型那到底怎么指定类型呢来看代码12345678910111213141516171819202122232425262728classMyArray T{//public Object[] array new Object[10];publicT[] array (T[])newObject[10];//这样写也不好待会说为什么publicT getPos(intpos) {returnarray[pos];}publicvoidsetPos(intpos, T value) {array[pos] value;}}publicclassTestDemo {publicstaticvoidmain(String[] args) {//我指定放整形MyArrayInteger myArray newMyArray();//后面的尖括号里的类型可以省略在实例化对象的时候根据前面可以做出判断//MyArrayInteger myArray new MyArrayInteger();myArray.setPos(0,1);myArray.setPos(1,2);Integer ret myArray.getPos(1);System.out.println(ret);//我指定放字符串类型MyArrayString myArray2 newMyArray();myArray2.setPos(0,abc);myArray2.setPos(1,bit);String ret2 myArray2.getPos(0);System.out.println(ret2);}}这个代码有几个注意事项1.尖括号里面只能放引用类型2.T是一个占位符代表当前类是一个泛型类3.MyArrayInteger array new MyArray();后面的尖括号可以省略Integer不写实例化对象的 时候编译器根据前面能做出判断。看完上面的代码我相信兄弟们已经明白是怎么一回事了吧我们刚刚的希望工程也已经实现了1.Integer指定当前类中使用的类型是Integer类型2.泛型帮我在编译期间做了2件事情目前为止的优点存放元素的时候进行类型的检查取元素的时候帮我进行类型的转换3.泛型类的语法有了刚刚知识的铺垫这一块咱就形式化一下啦当然语法还是很重要滴语法泛型类类型实参 变量名; // 定义一个泛型类引用new 泛型类类型实参(构造方法实参); // 实例化一个泛型类对象栗子1MyArrayInteger list newMyArrayInteger();4.裸类型说明兄弟们咱学了新东西这旧东西咱也得了解一下是不咯万一以后跟别人聊到了自己好像从来没听过就尴尬了裸类型是一个泛型类但没有带着类型实参例如 MyArrayList 就是一个裸类型1MyArray list newMyArray();注意 我们不要自己去使用裸类型裸类型是为了兼容老版本的 API 保留的机制5.泛型如何编译的5.1 擦除机制我用的是Powershell窗口查看的字节码文件当然用idea的兄弟们也可以去下载一个展示字节码的插件接下来我们看看泛型到底是怎么编译的javap -c查看字节码我们发现在编译期间所有的T都被擦除为了Object那既然所有的T都变成了Object那我们为什要指定类型呢注意这里不是编译的时候替换指定类型只是为了在编译的时候帮我们进行类型的检查和转换并不是替换最终字节码编译完成的时候所有的T变成了Object而这就是我们Java当中泛型所谓的擦除机制提问那既然T在编译的时候被擦除为了Object那为啥 T[] array new T[] 会报错呢5.2会给你答案5.2.泛型数组为什么不能实例化先看一段代码和运行结果12345678910111213classMyArrayT {publicT[] array (T[])newObject[10];publicT getPos(intpos) {returnthis.array[pos]; }publicvoidsetVal(intpos,T val) {this.array[pos] val; }publicT[] getArray() {returnarray; }}publicclassTestDemo {publicstaticvoidmain(String[] args) {MyArrayInteger myArray1 newMyArray();Integer[] strings myArray1.getArray();//这里运行时会报错String[] strings1 (String)myArray1.getArray();//这里编译都不能通过}}出现这种情况的原因何在呢这里最大的问题就是数组java中的数组是非常特殊的它是在堆上分配内存的它有自己的一套特殊的机制而T[] array new T[] 这个数组它没有指定具体的类型,肯定是不让这样做的再者get方法的返回类型是Object类型如果用整形数组来接受父类给子类编译器是直接不让你做的。