第二十一章 泛型(generic)

来源:互联网 发布:淘宝改差评先打钱 编辑:程序博客网 时间:2024/06/05 12:43
                         第二十一章 泛型(generic)
(1)引言
     泛型:是指参数化类型的能力。
     例如:有这样一个类:这是一个比较简单并且是很常用的带有泛型的方法。


     package com.lidd.generic;


     public class GenericTestSecond {

public <T>void one(T t){


}


      }


      下面是几个类,分别是一般类、抽象类、接口(接口也是特殊的类)。


      package com.lidd.generic;


      public class A {


      }


      package com.lidd.generic;


      public abstract class B {


      }


      package com.lidd.generic;


      public interface C {




     }


     接下里是主函数:
     package com.lidd.generic;
     public class MainTest {
public static void main(String[] args) {

GenericTestSecond o = new GenericTestSecond();
o.one(new C(){});   //C
o.one(new A());     // A
o.one(new B(){});   // B
o.one("bbbb");      // String
o.one(1);           // Integer

}


    }


    可以看到main方法中实例化了一个GenericTestSecond对象。方法one中传的参数类型可以是C、A、B、String、Integer等等,也就是说方法one中的泛型并不是指代某一种具体的类型
    而实在具体类型的基础上又进行了一层参数化。这就是定义中所说的参数化类型的能力。


   (2)泛型的优点。
        在jdk 1.5之前
package java,lang;
public interface Comparable{

public int compareTo(Object o);
}
在jdk1.5开始及其以后
package java.lang;
public interface Comparable<T>{
  public int compareTo(T t);
}




     1、泛型使得程序更加可靠。


     Comparable c = new Date();
     System.out.println(c.compareTo("red"));


     Comparable<Date> c = new Date();
     System.out.println(c.compareTo("red"));


     62 中一个时间和一个String字符串去做比较,但是在编译期不会有任何问题。但是在运行时会报错。
     65 中在编译的时候就会报错,因为Comparable中使用了泛型,并且在64行指定为Date类型。
     注意:
     泛型类型必须是应用类型,不能用像int double或char这样的基本类型来替换泛型类型。例如下面的语句是错误的:
     ArrayList<int> list = new ArrayList<int>();
     必须是ArrayList<Integer> list = new ArrayList<Integer>();
     2、无需类型转换。
     例如:
     ArrayList<String> strList = new ArrayList<String>();
     strList.add("one");
     strList.add("two");
     String str = strList.get(0);
     91 行不需要这样 String str = (String)strList.get(0);
     (3) 泛型的几种常见形式。
     1、泛型类(抽象类):
     public class GenericStack<E>{
private java.util.ArrayList<E> list = new java.util.ArrayList<E>();

public int getSize(){


return list.size();
}
public E peek(){
return list.get(getSize()-1);

}
public void push(E e){
list.add(e);

}
public E pop(){

E o = list.get(getSize()-1);
list.remove(getSize()-1);
return o;
}


public boolean isEmpty(){

return list.isEmpty();

}

  
     }
     或者是:


      public class GenericStack<E extends A>{
private java.util.ArrayList<E> list = new java.util.ArrayList<E>();

public int getSize(){


return list.size();
}
public E peek(){
return list.get(getSize()-1);

}
public void push(E e){
list.add(e);

}
public E pop(){

E o = list.get(getSize()-1);
list.remove(getSize()-1);
return o;
}


public boolean isEmpty(){

return list.isEmpty();

}

  
     }
    


     其中A为一个类。


      2、泛型接口:
      public interface Comparable<T>{
public int compareTo(T t);
      
      }
      或者是:
      public interface Comparable<T extends A>{
 public int compareTo(T t);
      
      }
   


      其中A为一个类。


      3、泛型方法:
      public class MyTest{
      
        // 注意<T>在方法的返回值类型之前
public <T>void one(T t){

}
      
      }


      或者:
      public class MyTest{
      
        // 注意<T>在方法的返回值类型之前
public <T extends A>void one(T t){

}
      
      }
  


      其中A为一个类。

     (4)通配泛型:
     以95行的类做前置准备。
     为啥需要通配泛型?
     pulic class demo1{
     
     public static void main(String[] args){
GenericStack<Integer> stack = new GenericStack<Integer>();
stack.add(1);
stack.add(2);
stack.add(3);
System.out.println("The max number is"+max(stack));
     
     }
    public static double max(GenericStack<Number> stack){
double max = stack.pop().doubleValue();
while(!stack.isEmpty()){
double value = stack.pop().doubleValue();
if(max < value){
max = value;
}
}
return max;
    
    }
     
  }


   其中208会出现编译错误,虽然Integer是Number的子类,但是GenericStack<Integer> 不是GenericStack<Number>的子类.
   这个时候通配泛型登场了。
   上面的代码稍加改动就可以消除208的编译错误。
   修改:211-221
   public static double max(GenericStack<? extends Number> stack){
double max = stack.pop().doubleValue();
while(!stack.isEmpty()){
double value = stack.pop().doubleValue();
if(max < value){
max = value;
}
}
return max;
    
    } 
    1、通配泛型的分类:
    第一类:?(非受限通配) 相当于 ?extends Object。
    例子:
    pulic class demo2{
     
     public static void main(String[] args){
GenericStack<Integer> stack = new GenericStack<Integer>();
stack.add(1);
stack.add(2);
stack.add(3);
print(stack);
     
     }
    public static double print(GenericStack<?> stack){


while(!stack.isEmpty()){
System.out.println(stack.pop()+"");
}
    
     }
     
   }
   注意253行-259行
   虽然GenericStack<?>相当于GenericStack<? extends Object>,但是不能是
     public static double print(GenericStack<Object> stack){


while(!stack.isEmpty()){
System.out.println(stack.pop()+"");
}
    
     } 


     否则的话250行编译不能通过。这是因为GenericStack<Integer> 不是GenericStack<Object>的子类。此处有体现的通配泛型的
     必要性。




    第二类:?extends T (受限通配) // 其中的T是某个泛型类型。
参考228-239行。




    第三类:?super T (下限通配)// 其中的T是某个泛型类型。


    public class demo3{

public static void main(String[] args){

GenericStack<String> stack1 = new GenericStack<String>();
GenericStack<Object> stack2 = new GenericStack<Object>();
stack1.add("java");
stack1.add("love");
stack2.add(1);
stack2.add(2);


add(stack1,stack2);

}
public static <T>void add(GenericSatck<T> stackTo,GenericStack<? super T> destStack){

while(!stackTo.isEmpty()){

destStack.push(stack1.pop());

}



}
    
    }


    296行如果使用<T>代替<? super T> ,那么293就会编译异常。


    (5)泛型消除:
    泛型是使用一种称为类型消除的方法来实现的。编译器使用泛型类型信息来编译代码,
    但是随后就会消除它。因此,泛型信息在运行时是不可用的。
    
//===========================================读java语言程序设计进阶篇笔记====================================================














0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 老是恶心想吐怎么回事 胃胀恶心想吐怎么回事 突然头疼恶心想吐是怎么回事 犯恶心想吐是怎么回事 天天恶心想吐怎么回事 恶心想吐拉肚子怎么回事 头晕耳鸣恶心想吐是怎么回事 头疼恶心吐怎么回事 恶心想吐拉肚子 咳嗽恶心想吐怎么回事 偏头疼恶心想吐是怎么回事 经常头疼恶心想吐是怎么回事 突然头痛恶心想吐是怎么回事 胃胀痛恶心是怎么回事 头痛 恶心 想吐 老是恶心是怎么回事 头疼加恶心是怎么回事 头晕头疼恶心想吐是怎么回事 头疼头晕恶心想吐是怎么回事 胃难受恶心想吐怎么回事 经常头晕恶心想吐是怎么回事 孕妇头晕恶心想吐是怎么回事 突然恶心想吐是怎么回事 恶心吐怎么回事 恶心想吐头晕 胃部不舒服恶心想吐 晚上恶心想吐是怎么回事 总恶心是怎么回事 恶心想吐头晕怎么回事 胃难受恶心怎么回事 来月经恶心想吐怎么回事 胃老是恶心怎么回事 老是头疼恶心怎么回事 为什么恶心想吐 经期恶心想吐是怎么回事 老是恶心想吐 头疼还恶心想吐咋回事 胃痛有点恶心想吐 感冒头晕恶心想吐是怎么回事 老是觉得恶心想吐是怎么回事 突然恶心想吐