Java

来源:互联网 发布:淘宝实木家具骗局真缘 编辑:程序博客网 时间:2024/06/05 13:22

泛型的作用

泛型,JDK1.5新加入的,解决数据类型的安全性问题,其主要原理是在类声明时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这样在类声明或实例化时只要指定好需要的具体的类型即可。Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。同时,代码更加简洁、健壮。

Map 类允许向一个 Map 添加任意类的对象,在给定映射(map)中保存某个特定类型(比如 String)的对象,因为 Map.get() 被定义为返回 Object,所以一般必须将 Map.get() 的结果强制类型转换为期望的类型,代码如下:

Map m = new HashMap();m.put("key", "blarg");String s = (String) m.get("key");  //强制转化

要让程序通过编译,必须将 get() 的结果强制类型转换为 String,并且希望结果真的是一个 String。但是有可能某人已经在该映射中保存了不是 String 的东西,这样的话,上面的代码将会抛出 ClassCastException。

泛型的声明及实例化

public class Test {    //泛型声明:interface List<T> 和 class TestGen<K,V>,其中,T,K,V不代表值,而是表示类型。这里使用任意字母都可以。常用T表示,是Type的缩写。*/    List<E> lz; //No    List<String> li;    //Yes    //实例化    List<String> list = new ArrayList<>();  //Yes    Iterator<String> iterator = list.iterator();    //Yes    //T只能是类,不能用基本数据类型填充。    List<Integer> list1 = new ArrayList<>();    //Yes    List<int> list2 = new ArrayList<>();    //No}

主要使用

1.在集合中使用泛型
泛型是Java中的一个重要概念,当元素存入集合时,集合会将元素转换为Object类型存储,当取出时也是按照Object取出的,所以用get方法取出时,我们会进行强制类型转换,并且通过代码也可以看出来,我们放入其他类型时,如字符串,编译器不会报错,但是运行程序时会抛出类型错误异常,这样给开发带来很多不方便,用泛型就解决了这个麻烦。
注意点如下:
1.1对象实例化时不指定泛型,默认为:Object
这里写图片描述
1.2加入集合中的对象类型必须与指定的泛型类型一致
这里写图片描述

2.泛型类
示例:

package com.v512.main1;class Infow<T>{      private T var ;        // 泛型变量      public void setVar(T var){          this.var = var ;      }      public T getVar(){          return this.var ;      }      public String toString(){              return this.var.toString() ;      }  };  public class GenericsDemo{      public static void main(String args[]){          Infow<String> i = new Infow<String>() ; // 使用String为泛型类型          i.setVar("String") ;// 设置变量的值         fun(i) ;        Infow<Integer> i2 = new Infow<Integer>() ;// 使用Integer为泛型类型          i2.setVar(11) ;// 设置变量的值          fun(i2) ;    }    public static void fun(Infow<?> infow){// 定义可以接收任意泛型对象的方法          System.out.println("Content:" + infow) ;      }};

设置上限:
2.1.在调用的方法中设置受限的类型

package com.v512.main2;class Info<T>  {      private T var;    //泛型变量       public T getVar() {          return var;      }      public void setVar(T var) {          this.var = var;      }      public String toString(){         return var.toString();      }}  public class GenericsDemo {          public static void main(String[] args) {          Info<Integer> info1 = new Info<Integer>(); // 声明Integer的泛型对象           Info<Float> info2 = new Info<Float>();  // 声明Float的泛型对象          Info<String> info3 = new Info<String>();           info1.setVar(10);  // 设置int型        info2.setVar(10F);  // 设置float型        info3.setVar("字符串");          fun(info1);        fun(info2);//      fun(info3);    //受限      }    /**     * 只能接收Number及其Number的子类      * @param temp     */      public static void fun(Info<? extends Number> temp){        System.out.println("内容:"+temp);    }}  

2.2定义泛型类的时候指定泛型上限

package com.v512.main3;class Info<T extends Number>{    // 此处泛型只能是数字类型及其子类      private T var ;        // 泛型变量      public void setVar(T var){          this.var = var ;      }      public T getVar(){          return this.var ;      }      public String toString(){         return this.var.toString() ;      }  }public class GenericsDemo{    public static void main(String args[]){          Info<Integer> i1 = new Info<Integer>() ;    // 声明Integer的泛型对象         Info<Float> i2 = new Info<Float>() ;        // 声明Integer的泛型对象         //Info<String>  info = new Info<String>();  //声明Integer的泛型对象    }  }

设置下限:

package com.v512.main4;import java.util.HashMap;import java.util.LinkedHashMap;class Info<T>{      private T var ;        // 泛型变量      public void setVar(T var){          this.var = var ;      }      public T getVar(){          return this.var ;      }      public String toString(){         return this.var.toString() ;      }};  public class GenericsDemo{    public static void main(String args[]){          Info<HashMap<String, String>> i1 = new Info<HashMap<String, String>>() ;        // 声明HashMap的泛型对象          Info<Object> i2 = new Info<Object>() ;        // 声明Object的泛型对象         Info<LinkedHashMap<String, String>> i3 = new Info<LinkedHashMap<String, String>>();// 声明LinkedHashMap的泛型对象        i1.setVar(new HashMap<String,String>()) ;          i2.setVar(new Object());        i3.setVar(new LinkedHashMap<String,String>());        fun(i1);        fun(i2);        //fun(i3);  //不支持LinkedHashMap    }      public static void fun(Info<? super HashMap<String, String>> temp){    // 只能接收HashMap或其父类的泛型          System.out.print(temp + "、") ;      }  };  

3.泛型接口
接口类型一:

package com.v512.main6;interface Info<T>{        // 在接口上定义泛型      public T getVar() ;    // 定义抽象方法,抽象方法的返回值就是泛型类型  }  class InfoImpl implements Info<String>{    // 定义泛型接口的子类      private String var ;                // 定义属性      public InfoImpl(String var){        // 通过构造方法设置属性内容          this.setVar(var) ;          }      public void setVar(String var){          this.var = var ;      }      public String getVar(){          return this.var ;      }  };public class GenericsDemo{      public static void main(String arsg[]){          Info i = null;        // 声明接口对象        i = new InfoImpl("soyoungboy") ;    // 通过子类实例化对象          System.out.println("内容:" + i.getVar()) ;      }  };  

接口类型二:

package com.v512.main7;interface Info<T>{        // 在接口上定义泛型      public T getVar() ;    // 定义抽象方法,抽象方法的返回值就是泛型类型}  class InfoImpl<T> implements Info<T>{    // 定义泛型接口的子类      private T var ;                // 定义属性    public InfoImpl(T var){        // 通过构造方法设置属性内容        this.setVar(var) ;    }    public void setVar(T var){        this.var = var ;    }    public T getVar(){        return this.var ;    }};public class GenericsDemo{    public static void main(String arsg[]){        Info<String> i = null;        // 声明接口对象          i = new InfoImpl<String>("soyoungboy") ;    // 通过子类实例化对象        System.out.println("内容:" + i.getVar()) ;    }};

4.泛型方法
泛型方法定义:访问权限 +<泛型标示>+泛型标示 方法名称(泛型标示 参数名称)

package com.v512.main8;class Demo{      public <T> T fun(T t){            // 可以接收任意类型的数据          return t ;                    // 直接把参数返回      }  };  public class GenericsDemo{      public static void main(String args[]){          Demo d = new Demo()    ;    // 实例化Demo对象          String str = d.fun("soyoungboy") ; //    传递字符串          int i = d.fun(30) ;        // 传递数字,自动装箱          System.out.println(str) ;    // 输出内容          System.out.println(i) ;        // 输出内容      }};

通过泛型方法返回泛型类的实例

package com.v512.main9;class Info<T extends Number>{    // 指定上限,只能是数字类型    private T var ;        // 此类型由外部决定    public T getVar(){          return this.var ;          }      public void setVar(T var){          this.var = var ;      }      public String toString(){        return this.var.toString() ;          }  };  public class GenericsDemo{    public static void main(String args[]){        Info<Integer> i = fun(30) ;        System.out.println(i.getVar()) ;    }    public static <T extends Number> Info<T> fun(T param){          Info<T> temp = new Info<T>() ;      // 根据传入的数据类型实例化Info        temp.setVar(param) ;        return temp ;    // 返回实例化对象    }  }; 

如果同一方法参数使用泛型,应该保证泛型类型一致:

package com.v512.main10;class Info<T>{    // 指定上限,只能是数字类型    private T var ;        // 此类型由外部决定    public T getVar(){          return this.var ;          }      public void setVar(T var){          this.var = var ;      }      public String toString(){        return this.var.toString() ;     }};public class GenericsDemo{    public static void main(String args[]){        Info<Integer> i1 = new Info<Integer>() ;        Info<String> i2 = new Info<String>() ;        i1.setVar(30) ;        // 设置内容        i2.setVar("aoyoungboy") ;        // 设置内容        add(i1,i2) ; //报错:The method add(Info<T>, Info<T>) in the type GenericsDemo is not applicable for the arguments (Info<Integer>, Info<String>)    }      public static <T> void add(Info<T> i1,Info<T> i2){          System.out.println(i1.getVar() + " " + i2.getVar()) ;      }  };  

泛型和继承的关系

如果B是A的一个子类型(子类或者子接口),而G是具有泛型声明的类或接口,G< B >并不是G< B >的子类型!

比如:String是Object的子类,但是List< String >并不是List< Object >的子类。

0 0