深入理解java泛型详解,java泛型的用法

  深入理解java泛型详解,java泛型的用法

  

目录

1.什么是泛型2。派生泛型3。泛型类的语法4。裸体类型5。如何编译泛型5.1擦除机制5.2?为什么泛型数组不能实例化6。泛型的上界7。通配符7.1。7.2可以用什么通配符?通配符上限(读取数据)7.3。通配符的下限(写入数据)。

 

  

1.什么是泛型

泛型是JDK1.5中引入的新语法,一般来说,泛型适用于很多很多类型。从代码的角度来看,类型是参数化的。

 

  有些兄弟看到这句红色的话可能会很困惑。我们过去传递参数,但它是一个整形数据和一个引用。我从来没有通过类型测试。类型还能作为参数传递吗?马鞭马鞭是的,没错。接下来,让我们看看类型作为参数传递的实现。

  

2.引出泛型

我们以前研究过遗传和多态性。我们知道所有类的父类默认都是Object class。我们现在的目标是:任何类型的数据都可以存储在数组中。这时,我们可以创建一个对象类型的数组,

 

  class MyArray { public Object[]array=new Object[10];public Object get pos(int pos){ return array[pos];} public void setPos(int pos,Object value){ array[pos]=value;} } public class test demo { public static void main(String[]args){ MyArray MyArray=new MyArray();myArray.setPos(0,1);myArray.setPos(1, hello );}}当我们写这样的代码时,发现数组中的所有元素都可以放,比如整形数据,字符串,小数。可以放进去的东西太多了。你能知道带下标的元素是什么样的吗?马鞭当我们取元素的时候,会发现你的代码无法编译,

  为什么会这样?相信大部分兄弟都知道我们观察到getPos的返回值是Object,也就是说我们取出来的可能是任意元素,但是编译器知道吗?马鞭马鞭它只知道它返回一个对象:这是显而易见的。父类给子类。这不是纯粹的向下转型吗?向下转换必须强制类型,否则您的代码不会通过。

  那么问题又来了。我这里只是放了两个元素,肉眼还是能看出来的,但是里面的类型一直在变。即使知道类型,也需要每次都强转吗?我是动态的,我的代码写死了,所以这个地方如果用Object来做,会特别麻烦,局限性非常大。

  我们现在面临两个困境:

  1.什么类型都可以玩,而且不好控制,

  2.每当你获取一个元素,你必须转换类型,

  这个时候,我们不得不搞希望工程。我们的希望是:

  1.我们可以自己指定类型吗?

  2.能不能停止类型转换,省略这一步,兄弟!

  为了解决这个问题,我们java引入了这个东西——泛型。

  那么如何指定类型呢?让我们看看代码:

  class MyArray T {//public Object[]array=new Object[10];public T[]array=(T[])new Object[10];//这样写也不好。为什么以后会说?马鞭public T get pos(int pos){ return array[pos];} public void setPos(int pos,T value){ array[pos]=value;}} public class测试演示{ public static void main(string[]args){//我指定放shape myarray integer myarray=new myarray();//后面尖括号中的类型可以省略,实例化对象时可以根据前面进行判断。//myarrayInteger myarray=newmyarrayInteger();myArray.setPos(0,1);myArray.setPos(1,2);integer ret=myarray . get pos(1);system . out . println(ret);//我指定字符串类型MyArrayStrin。

  g> myArray2 = new MyArray<>(); myArray2.setPos(0,"abc"); myArray2.setPos(1,"bit"); String ret2 = myArray2.getPos(0); System.out.println(ret2); }}这个代码有几个注意事项:

  1.尖括号<>里面只能放引用类型;

  2.<T>是一个占位符,代表当前类是一个泛型类;

  3.MyArray<Integer> array = new MyArray<>();后面的尖括号可以省略Integer不写,实例化对象的 时候编译器根据前面能做出判断。

  看完上面的代码,我相信兄弟们已经明白是怎么一回事了吧

  我们刚刚的希望工程也已经实现了

  1.<Integer>,指定当前类中,使用的类型是Integer类型

  2.泛型帮我在编译期间做了2件事情(目前为止的优点):

  存放元素的时候,进行类型的检查取元素的时候,帮我进行类型的转换

 

  

3.泛型类的语法

有了刚刚知识的铺垫,这一块咱就形式化一下啦,,当然,语法还是很重要滴!!

 

  语法:

  

泛型类<类型实参> 变量名; // 定义一个泛型类引用new 泛型类<类型实参>(构造方法实参); // 实例化一个泛型类对象

 

  

栗子:

 

  

MyArray<Integer> list = new MyArray<Integer>();

 

  

4.裸类型

说明:

 

  兄弟们,咱学了新东西,这旧东西,咱也得了解一下是不咯,,万一以后跟别人聊到了,自己好像从来没听过就尴尬了,,

  裸类型是一个泛型类但没有带着类型实参,例如 MyArrayList 就是一个裸类型

  

MyArray list = new MyArray();

注意: 我们不要自己去使用裸类型,裸类型是为了兼容老版本的 API 保留的机制

 

  

 

  

5.泛型如何编译的

 

  

5.1 擦除机制

我用的是Powershell窗口查看的字节码文件,当然用idea的兄弟们也可以去下载一个展示字节码的插件,,接下来我们看看泛型到底是怎么编译的,,javap -c查看字节码

 

  

 

  我们发现在编译期间,所有的T都被擦除为了Object,那既然所有的T都变成了Object,那我们为什要指定类型呢?注意这里不是编译的时候替换,指定类型只是为了在编译的时候帮我们进行类型的检查和转换,并不是替换!!!最终字节码编译完成的时候,所有的T变成了Object,而这就是我们Java当中泛型所谓的擦除机制!!!

  提问:那既然T在编译的时候被擦除为了Object,那为啥 T[] array = new T[] 会报错呢?

  5.2会给你答案

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: