泛型编程

五迷三道 提交于 2019-12-02 01:55:28

      泛型编程:写的代码可以处理任何的类型。(例如,当你要新建立一个数组时,但还不确定该数组的类型

可能后面要用的是整型数组,也可能要用的是字符串型数组,甚至栈类型数组。但因为Object类是所有类的

基类,所以此时只要将该数组定义成Object类型,这样其他的每个类型的数组都可以使用该Object类型的数

组,这就是泛型编程。)

   

  在早期Java 5版本出现之前,人们要实现泛型编程,都是将类型定义成Object类型来实现的。

 1 package L14;
 2 import java.util.Arrays;
 3 
 4 public class ObjectTest {
 5     private  Object[] array;   //定义一个Object类数组
 6     private  int size;   //存储数据元素个数
 7 
 8     public ObjectTest(int size){
 9         this.array= new Object[size];  //给数组初始化   //一般新new的都是对象,而T只是个类型参数
10         this.size=0;
11     }
12     public ObjectTest(){
13         this(10);
14     }
15     public void add(Object data){     //将添加的元素定义成Object类型
16         if(this.size==this.array.length){   //当数组满了,要进行扩容
17             this.array=Arrays.copyOf(this.array,this.array.length*2);
18         }
19         this.array[this.size++]=data;
20     }
21     public Object back() {
22         if(this.size==0){     //当数组内空了,return null
23             return null;   //因为引用类型的默认初始值为null
24         }
25         return this.array[this.size-1]; //因为只返回,并不从栈中取出,所以进行size-1,而不是size--
26     }
27     public static void main(String[] args) {
28            ObjectTest o=new ObjectTest();   //Object 类的构造函数会自动给O对象数组进行初始化
29            o.add(10);   //因为Object类是所有类的基类,所以任何类型都可存到Object类的数组中
30            o.add(20);
31            o.add("30");
32           String data1=(String) o.back();
33         System.out.println(data1);
34         }
35     }

运行结果:

 

      这是在使用者可以确保完全输入正确的情况下的,但是如果这次该用户想用Object类型的数组来

实现整型数组,但因为手误,而错输进一个字符串,这时编译是检测不到的。

 只有在运行之后才会报错。(所以用Object类型来实现泛型编程存在好多弊端)

弊端: 1.无法检测传入的数据是否符合用户存储数据的正确类型

         2.输出时,需要手动进行类型的强制转换。

 

 

     所以在java5版本后,为了解决上述的两个问题,就出现了真正的泛型编程。

泛型编程的本质意义:1.检测传入的数据是否符合用户存储数据的正确类型

               2.自动转换类型,无需用户手动进行类型的强制转换

 1 public class GenericTest<T> {
 2     private  T[] array;   //定义一个T类型的泛型数组
 3     private  int size;    //存储数据元素个数
 4 
 5     public GenericTest(int size){
 6         this.array=(T[]) new Object[size];  //将接收的Object类型强置转换为T类型
 7         this.size=0;
 8     }
 9     public GenericTest(){
10         this(10);
11     }
12     public void add(T data){    //添加一个T类型的数组
13         if(this.size==this.array.length){
14             this.array=Arrays.copyOf(this.array,this.array.length*2);
15         }
16         this.array[this.size++]=data;
17     }
18     public T  back(){    //返回一个T类型的数
19         if(this.size==0){   //当数组为空时,返回null。
20             return null;    //因为null为引用变量的初始值
21         }
22         return array[this.size-1];
23     }
24 
25     public static void main(String[] args) {
26         GenericTest<String>  text=new GenericTest(12);   //
27         text.add("20");
28         text.add("30");
29         String str=text.back();
30         System.out.println(str);
31     }
32 }

        就是在开头类名后加一个尖括号<>,在尖括号内放入类型参数,(普通类类名+< 类型参数>),需要注意的是

该类型参数必须全为大写,如T,E,R等,然后在定义数组时,也将数组定义成T类型的,在构造函数中对数组初始化

时,将新new的Object类型也强置转换为T类型(因为一般new 对象时,要放具体的类型,而T只是类型参数,)。

然后在后面写成员方法时,将传入的值,或返回的值也要定义成T类型的。最后就是在main方法中新new对象时,

将你要定义的真正的类型写上,如要定义字符串数组,GenericTest<String>  text=new GenericTest(12);  

 

 

   这样,当你输入的数据类型有错时,就会直接报错。也省略了手动对类型转换的过程。

 需要注意,当确定一个泛型类型后,仍可以继续使用原始类型。但该类型还是会有之前的弊端(2个)。

此时相当于给T赋的是Object。

 

 

 

 之所以还可以使用原始类型,是因为泛型在java5之后出现,若要强制必须给T赋类型的话,那么在5之前写的

那些代码(没有T类型)都会报错不能使用。

 

java泛型的类型擦除机制???

    在编译阶段,Java编译器通过泛型类型进行类型检查和自动类型转换,处理完以后,就会把T类型一直往上

擦除(进行类型检查),直到上界(默认为Object类),所以在运行阶段都是以Object类型来运行。

 

所以在Java中认为     GenericTest <Interage>    这两个是同一类型的。(C语言中认为是两种)

                GenericTest <String>      

 

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!