Java知识点总结之Java泛型

泛型

泛型就是参数化类型
  • 适用于多种数据类型执行相同的代码
  • 泛型中的类型在使用时指定
  • 泛型归根到底就是“模版”
优点:使用泛型时,在实际使用之前类型就已经确定了,不需要强制类型转换。
泛型主要使用在集合中
import java.util.ArrayList;
import java.util.List;

publicclassDemo01{

 // 不使用泛型,存取数据麻烦
 publicstaticvoidtest1(){
   List  list = new ArrayList();
   list.add(100);
   list.add(“zhang”);
   /*
    * 从集合中获取的数据是Object类型,Object类型是所有类型的根类,但是在具体使用的时候需要
    * 类型检查,类型转化,处理类型转化异常
    * 使用麻烦
    */
   Object o = list.get(1);
   if (o instanceof String) {
    String s = (String)o;
   }
   System.out.println(o);
 }

 // 使用泛型
 publicstaticvoidtest2(){
   List<String> list = new ArrayList<String>();
   //list.add(100); 放数据时安全检查,100不是String类型,不能存放
   list.add(“存数据安全,取数据省心”);
   String s = list.get(0); //取出来的数据直接就是泛型规定的类型
   System.out.println(s);

 }

 publicstaticvoidmain(String[] args){
   test1();
   test2();
 }

}

自定义泛型


泛型字母

  • 形式类型参数(formal type parameters)即泛型字母
  • 命名泛型字母可以随意指定,尽量使用单个的大写字母(有时候多个泛型类型时会加上数字,比如T1,T2)
    常见字母(见名知意)
    • T Type
    • K V Key Value
    • E Element
  • 当类被使用时,会使用具体的实际类型参数(actual type argument)代替

泛型类

  • 只能用在成员变量上,只能使用引用类型

泛型接口

  • 只能用在抽象方法上

泛型方法


  • 返回值前面加上 <T>
/**
* 自定义泛型类
*
* 定义”模版”的时候,泛型用泛型字母:T 代替
* 在使用的时候指定实际类型
*
* @author Administrator
* @param <T>
*/
publicclassStudent<T> {

 private T javase;

 //private static T javaee;   // 泛型不能使用在静态属性上

 publicStudent(){
 }

 publicStudent(T javase){
   this();
   this.javase = javase;
 }

 public T getJavase(){
   return javase;
 }

 publicvoidsetJavase(T javase){
   this.javase = javase;
 }

}
/**
* 自定义泛型的使用
* 在声明时指定具体的类型
* 不能为基本类型
* @author Administrator
*
*/
classDemo02{
 publicstaticvoidmain(String[] args){
   //Student<int>  Student = new Student<int>(); //不能为基本类型,编译时异常

   Student<Integer> student = new Student<Integer>();
   student.setJavase(85);
   System.out.println(student.getJavase());  
 }
}

/**
* 自定义泛型接口
*
* 接口中泛型字母只能使用在方法中,不能使用在全局常量中
*
* @author Administrator
* @param <T>
*/
publicinterfaceComparator<T1,T2> {

 //public static final T1 MAX_VALUE = 100; //接口中泛型字母不能使用在全局常量中
 //T1 MAX_VALUE;
 publicstaticfinalint MAX_VALUE = 100;

 voidcompare(T2 t);
 T2 compare();
 publicabstract T1 compare2(T2 t);
}

import java.io.Closeable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.List;


/**
* 非泛型类中定义泛型方法
* @author Administrator
*
*/
publicclassMethod{

 // 泛型方法,在返回类型前面使用泛型字母
 publicstatic <T> voidtest1(T t){
   System.out.println(t);
 }

 // T 只能是list 或者list 的子类
 publicstatic <T extends List> voidtest2(T t){
   t.add(“aa”);
 }

 // T… 可变参数   —>   T[]
 publicstatic <T extends Closeable> voidtest3(T…a){
   for (T temp : a) {
    try {
      if (null != temp) {
        temp.close();
      }
    } catch (Exception e) {
      e.printStackTrace();
    }

   }
 }

 publicstaticvoidmain(String[] args)throws FileNotFoundException {
   test1(“java 是门好语言”);
   test3(new FileInputStream(“a.txt”));
 }
}

泛型的继承

/**
* 泛型继承
*
* 保留父类泛型 —-》泛型子类
* 不保留父类泛型 —–》子类按需实现
*
* 子类重写父类的方法,泛型类型随父类而定 子类使用父类的属性,该属性类型随父类定义的泛型
*
* @author Administrator
*
* @param <T1>
* @param <T2>
*/
publicabstractclassFather<T1, T2> {
 T1 age;

 publicabstractvoidtest(T2 name);
}

// 保留父类泛型 —-》泛型子类
// 1)全部保留
classC1<T1, T2> extendsFather<T1, T2> {

 @Override
 publicvoidtest(T2 name){

 }
}

// 2) 部分保留
classC2<T1> extendsFather<T1, Integer> {

 @Override
 publicvoidtest(Integer name){

 }
}

// 不保留父类泛型 —–》子类按需实现
// 1)具体类型
classC3extendsFather<String, Integer> {

 @Override
 publicvoidtest(Integer name){

 }
}

// 2)没有具体类型
// 泛型擦除:实现或继承父类的子类,没有指定类型,类似于Object
classC4extendsFather{

 @Override
 publicvoidtest(Object name){

 }

}

/**
* 泛型擦除
* 类似于Object,不等于Object
* @author Administrator
*
*/
publicclassDemo03{

 publicstaticvoidtest(Student<Integer> student){
   student.setJavase(100);
 }

 publicstaticvoidmain(String[] args){
   // 泛型擦除
   Student student = new Student();
   test(student);

   Student<Object> student2 = new Student<Object>();
   //test(student2);  //编译异常
 }

}

通配符

通配符(Wildcards)
  • T、K、V、E 等泛型字母为有类型,类型参数赋予具体的值
  • ?未知类型 类型参数赋予不确定值,任意类型
  • 只能用在声明类型、方法参数上,不能用在定义泛型类上
/**
* 泛型的通配符 类型不确定,用于声明变量或者形参上面
*
* 不能使用在类上 或者  new 创建对象上
* @author Administrator
*
*/
publicclassDemo04{

 // 用在形参上
 publicstaticvoidtest(List<?> list){

  List<?> list2; // 用在声明变量上
  list2 = new ArrayList<String>();
  list2 = new ArrayList<Integer>();
  list2 = new ArrayList<Object>();

 }

 publicstaticvoidmain(String[] args){
  test(new ArrayList<String>());
  test(new ArrayList<Integer>());
 }

}

extends/super


上限(extends)

指定的类必须是继承某个类,或者实现了某个接口(不是implements),即<=
  • ? extends List

下限(super)

即父类或本身
  • ? super List
import java.util.ArrayList;
import java.util.List;

/**
* extends:泛型的上限 <= 一般用于限制操作 不能使用在添加数据上,一般都是用于数据的读取
*
* supper:泛型的上限 >= 即父类或自身。一般用于下限操作
*
* @author Administrator
* @param <T>
*/

publicclassTest<TextendsFruit> {

 privatestaticvoidtest01(){
   Test<Fruit> t1 = new Test<Fruit>();
   Test<Apple> t2 = new Test<Apple>();
   Test<Pear> t3 = new Test<Pear>();
 }

 privatestaticvoidtest02(List<? extends Fruit> list){

 }

 privatestaticvoidtest03(List<? super Apple> list){

 }

 publicstaticvoidmain(String[] args){

   // 调用test02(),测试 extends  <=
   test02(new ArrayList<Fruit>());
   test02(new ArrayList<Apple>());
   test02(new ArrayList<ReadApple>());
   // test02(new ArrayList<Object>()); Object 不是 Fruit 的子类 ,编译不通过


   // 调用test03() ,测试super >=
   test03(new ArrayList<Apple>());
   test03(new ArrayList<Fruit>());
   //test03(new ArrayList<ReadApple>());  ReadApple < apple,所以不能放入
 }

}

classFruit{

}

classAppleextendsFruit{

}

classPearextendsFruit{

}

classReadAppleextendsApple{

}

泛型嵌套

从外向里取
import java.util.Map.Entry;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
* 泛型嵌套
* @author Administrator
*
*/
publicclassDemo05{


 publicstaticvoidmain(String[] args){
   Student2<String> student = new Student2<String>();
   student.setScore(“优秀”);
   System.out.println(student.getScore());

   //泛型嵌套
   School<Student2<String>> school = new School<Student2<String>>();
   school.setStu(student);

   String s = school.getStu().getScore(); //从外向里取
   System.out.println(s);

   // hashmap 使用了泛型的嵌套
   Map<String, String> map =  new HashMap<String,String>();
   map.put(“a”, “张三”);
   map.put(“b”, “李四”);
   Set<Entry<String, String>> set = map.entrySet();
   for (Entry<String, String> entry : set) {
    System.out.println(entry.getKey()+“:”+entry.getValue());
   }

 }
}

publicclassSchool<T> {
 private T stu;

 public T getStu(){
   return stu;
 }

 publicvoidsetStu(T stu){
   this.stu = stu;
 }

}

publicclassStudent2<T> {
 T score;

 public T getScore(){
   return score;
 }

 publicvoidsetScore(T score){
   this.score = score;
 }
}

其他

import java.util.ArrayList;
import java.util.List;

/**
* 泛型没有多态
* 泛型没有数组
* JDK1.7对泛型的简化
* @author Administrator
*
*/
publicclassDemo06{

 publicstaticvoidmain(String[] args){
   Fruit fruit = new Apple();  // 多态,父类的引用指向子类的对象
   //List<Fruit> list = new ArrayList<Apple>(); //泛型没有多态
   List<? extends Fruit> list = new ArrayList<Apple>();

   //泛型没有数组
   //Fruit<String>[] fruits = new Fruit<String>[10];

   //ArrayList底层是一个Object[],它放数据的时候直接放,取数据的时候强制类型转化为泛型类型
   /*public boolean add(E e) {
         ensureCapacityInternal(size + 1);  // Increments modCount!!
         elementData[size++] = e;
         return true;
     }*/

   /*E elementData(int index) {
         return (E) elementData[index];
     }*/


   //JDK1.7泛型的简化,1.6编译通不过
   List<Fruit> list2 = new ArrayList<>();
 }
}


    本站所有文章均由网友分享,仅用于参考学习用,请勿直接转载,如有侵权,请联系网站客服删除相关文章。若由于商用引起版权纠纷,一切责任均由使用者承担
    极客文库 » Java知识点总结之Java泛型

    Leave a Reply