A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© javaeea 中级黑马   /  2015-9-26 21:37  /  798 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

学习java或者软件开发的出去编程有时候项目经理经常会问到有关泛型的理解;

泛型:是指在定义类或者接口的时候可以为类和接口指定类型形参,在定义变量、定义方法是该类型形参可以当做普通的类型来使用,并且该类型形参在定义变量和创建对象的确定

1、定义泛型类,程序实例代码如下:



[java] view plaincopy

01.<span style="font-size:18px">public class GenericClass<E> {  
02.    /**
03.     * @param args
04.     * 自定义泛型类
05.     */   
06.    private E e;//变量  
07.      
08.    public GenericClass(){  
09.         
10.    }     
11.    public GenericClass(E e){  
12.        this.e=e;  
13.    }     
14.    public E getE(){//返回值类型  
15.        return e;  
16.    }     
17.    public void println(E e){//函数参数  
18.        System.out.println(e);  
19.    }  
20.    public static void main(String[] args) {  
21.        GenericClass<Integer> gc=new GenericClass<Integer>();  
22.        gc.println(1111111);  
23.         
24.        GenericClass<String> gc1=new GenericClass<String>();  
25.        gc1.println("string");  
26.                     
27.    }  
28.}</span>  

2、实现泛型接口,在实现泛型接口或者类的时候,可以不指定类型形参,但是编译的时候会出现警告;



[java] view plaincopy

01.public interface InterfaceGeneric<E> {         
02.    public E getE();  
03.    public void save(E e);   
04.}  



[java] view plaincopy

01.public class InterfaceImplement implements InterfaceGeneric<Integer>{  
02.    /**
03.     * @param args
04.     */  
05.    @Override  
06.    public Integer getE() {  
07.        // TODO Auto-generated method stub  
08.        return null;  
09.    }  
10.    @Override  
11.    public void save(Integer e) {  
12.        // TODO Auto-generated method stub  
13.         
14.    }  
15.    public static void main(String[] args) {  
16.        // TODO Auto-generated method stub  
17.         
18.    }  
19.}  

3、类型通配符

在定义一个方法的时候,如果该方法的参数为集合形参,集合的元素类型是不确定的,那我们该怎么定义呢?

假如如下所示的定义:



[java] view plaincopy

01.<span style="font-size:18px">// public void println(List<Object> list){//函数参数  
02.//      int count=list.size();  
03.//      for(int i=0;i<count;i++){  
04.//          System.out.println(list.get(i));  
05.//      }  
06.//  }</span>  



[java] view plaincopy

01.<span style="font-size:18px">  List<String> list=new ArrayList<String>();  
02.  list.add("a");   
03.  //println(list);不正确,因为List<String>不是List<Object>的子类</span>  

那么这样的使用方法是不正确的,因为函数的形参是List<Object>类型的,而实参是List<String>类型的,但是需要注意的一点是List<String>并不是List<Object>的子类,所以这样写是不正确的,那么在这个list里的元素类型不确定的情况下怎么定义这个函数呢,这就用到了类型通配符;在java中类型通配符是一个?;类型通配符是所有泛型List的父类,在定义函数的时候用?代替类型,就可以在以后使用的时候定义各种各样的类型的List集合,如下的程序实例所示:



[java] view plaincopy

01.<span style="font-size:18px">   public void println(List<?> list){//函数参数List使用类型通配符  
02.        int count=list.size();  
03.        for(int i=0;i<count;i++){  
04.            System.out.println(list.get(i));  
05.        }  
06.    }</span>  



[java] view plaincopy

01.<span style="font-size:18px">  
02.        List<String> list=new ArrayList<String>();  
03.        list.add("a");        
04.        gc.println(list);</span>  

4、类型通配符上限

定义一个形状类,有一个画图的方法,可以画各种各样的形状,则可以定义为接口如下所示:



[java] view plaincopy

01.<span style="font-size:18px">public interface Shape {  
02.    public void draw();  
03.}</span>  

定义一个圆类和矩形类,分别实现上面定义的接口,然后重写方法draw();



[java] view plaincopy

01.<span style="font-size:18px">public class Rectangle implements Shape {  
02.  
03.    @Override  
04.    public void draw() {  
05.        // TODO Auto-generated method stub  
06.        System.out.println("draw a rectangle");  
07.    }  
08.  
09.}  
10.public class Circle implements Shape {  
11.  
12.    @Override  
13.    public void draw() {  
14.        // TODO Auto-generated method stub  
15.        System.out.println("draw a circle");  
16.    }  
17.  
18.}  
19.  
20.</span>  

假如有一个画布可以画很多图形,则可以这样定义该画布类:



[java] view plaincopy

01.<span style="font-size:18px">public class Canves {  
02.    /**
03.     * @param args
04.     */  
05.//这里使用List<Shape>不正确,会出现编译错误,因为List<Circle> List<Rectangle>不是List<Shape>的子类  
06.//  public void draw(List<Shape> shapeList){  
07.//        
08.//  }  
09.      
10.    /*
11.     *可以考虑使用类型通配符的方式List<?>
12.     *但是这里使用的类型通配符是配的所有的类型,所以加进去的元素就是Object类型的
13.     *这里需要强制类型转换,降低了程序的执行效率;所以可以使用java提供的类型通配符的上限定义方法
14.     **/  
15.//  public void draw(List<?> shapeList){  
16.//      for(Object obj:shapeList){  
17.//          Shape shape=(Shape)obj;  
18.//          shape.draw();   
19.//      }  
20.//  }  
21.    /*
22.     *这里使用类型通配符的上限的形式定义list集合的元素类型List<? extends Shape>
23.     * */  
24.    public void draw(List<? extends Shape> shapeList){  
25.        for(Shape shape:shapeList){           
26.            shape.draw();  
27.        }  
28.    }  
29.      
30.    public static void main(String[] args) {         
31.        Canves c=new Canves();  
32.        List<Circle> listCircle=new ArrayList<Circle>();  
33.        listCircle.add(new Circle());  
34.         
35.        List<Rectangle> listRectangle=new ArrayList<Rectangle>();  
36.        listRectangle.add(new Rectangle());  
37.         
38.        c.draw(listCircle);//   1  
39.        c.draw(listRectangle);//    2  
40.    }  
41.}  
42.</span>  


  

draw()方法的参数里list集合的类型使用的是类型通配符的上限形式,这样既可以往list集合中添加不同的Shape类子类的对象,而且不用进行强制类型转换。

5、泛型方法

泛型方法的使用效果和类型通配符非常相似



[java] view plaincopy

01.<span style="font-size:18px">public class GenericMethod {  
02.    //泛型方法  
03.    public <E> void genericmethod(List<E> a){  
04.         
05.        for(E t:a)  
06.            System.out.println(t.toString());  
07.         
08.    }  
09.         
10.    public static void main(String[] param){  
11.        List<String> list=new ArrayList<String>();  
12.        list.add("dfd");  
13.        list.add("dfd");  
14.        list.add("dfd");  
15.        list.add("dfd");  
16.        new GenericMethod().genericmethod(list);  
17.         
18.        List<Integer> list1=new ArrayList<Integer>();  
19.        list1.add(1);  
20.        list1.add(2);  
21.        list1.add(3);  
22.        list1.add(4);  
23.        new GenericMethod().genericmethod(list1);                 
24.    }     
25.}</span>  

2 个回复

倒序浏览
666666666666666666
回复 使用道具 举报
认同,我也是这样理解的,就是方法中参数机制的一种推广
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马