Java知識點總結(Java泛型)

Java知識點總結(Java泛型)

@(Java知識點總結)[Java, Java泛型]java

[toc]數組

泛型

泛型就是參數化類型安全

  • 適用於多種數據類型執行相同的代碼
  • 泛型中的類型在使用時指定
  • 泛型歸根到底就是「模版」

優勢:使用泛型時,在實際使用以前類型就已經肯定了,不須要強制類型轉換。app

泛型主要使用在集合中ide

import java.util.ArrayList;
import java.util.List;
 
public class Demo01 {
  
  // 不使用泛型,存取數據麻煩
  public static void test1(){
    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);
  }
  
  // 使用泛型
  public static void test2(){
    List<String> list = new ArrayList<String>();
    //list.add(100); 放數據時安全檢查,100不是String類型,不能存放
    list.add("存數據安全,取數據省心");
    String s = list.get(0); //取出來的數據直接就是泛型規定的類型
    System.out.println(s);
    
  }
  
  public static void main(String[] args) {
    test1();
    test2();
  }
 
}

自定義泛型

泛型字母

  • 形式類型參數(formal type parameters)即泛型字母
  • 命名泛型字母能夠隨意指定,儘可能使用單個的大寫字母(有時候多個泛型類型時會加上數字,好比T1,T2)
    常見字母(見名知意)測試

    • T Type
    • K V Key Value
    • E Element
  • 當類被使用時,會使用具體的實際類型參數(actual type argument)代替

泛型類

  • 只能用在成員變量上,只能使用引用類型

泛型接口

  • 只能用在抽象方法上

泛型方法

  • 返回值前面加上 &ltT&gt


/**
 * 自定義泛型類
 *
 * 定義"模版"的時候,泛型用泛型字母:T 代替
 * 在使用的時候指定實際類型
 *
 * @author Administrator
 * @param <T>
 */
public class Student<T> {
  
  private T javase;
  
  //private static T javaee;   // 泛型不能使用在靜態屬性上
 
  public Student() {
  }
 
  public Student(T javase) {
    this();
    this.javase = javase;
  }
 
  public T getJavase() {
    return javase;
  }
 
  public void setJavase(T javase) {
    this.javase = javase;
  }
  
}
/**
 * 自定義泛型的使用
 * 在聲明時指定具體的類型
 * 不能爲基本類型
 * @author Administrator
 *
 */
class Demo02 {
  public static void main(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>
 */
public interface Comparator<T1,T2> {
  
  //public static final T1 MAX_VALUE = 100; //接口中泛型字母不能使用在全局常量中
  //T1 MAX_VALUE;
  public static final int MAX_VALUE = 100;
  
  void compare(T2 t);
  T2 compare();
  public abstract T1 compare2(T2 t);
}


import java.io.Closeable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.List;
 
 
/**
 * 非泛型類中定義泛型方法
 * @author Administrator
 *
 */
public class Method {
 
  // 泛型方法,在返回類型前面使用泛型字母
  public static <T> void test1(T t){
    System.out.println(t);
  }
  
  // T 只能是list 或者list 的子類
  public static <T extends List> void test2(T t){
    t.add("aa");
  }
  
  // T... 可變參數   --->   T[]
  public static <T extends Closeable> void test3(T...a) {
    for (T temp : a) {
     try {
       if (null != temp) {
         temp.close();
       }
     } catch (Exception e) {
       e.printStackTrace();
     }
     
    }
  }
  
  public static void main(String[] args) throws FileNotFoundException {
    test1("java 是門好語言");
    test3(new FileInputStream("a.txt"));
  }
}

泛型的繼承

/**
 * 泛型繼承
 *
 * 保留父類泛型 ----》泛型子類 
 * 不保留父類泛型 -----》子類按需實現
 *
 * 子類重寫父類的方法,泛型類型隨父類而定 子類使用父類的屬性,該屬性類型隨父類定義的泛型
 *
 * @author Administrator
 *
 * @param <T1>
 * @param <T2>
 */
public abstract class Father<T1, T2> {
  T1 age;
 
  public abstract void test(T2 name);
}
 
// 保留父類泛型 ----》泛型子類
// 1)所有保留
class C1<T1, T2> extends Father<T1, T2> {
 
  @Override
  public void test(T2 name) {
 
  }
}
 
// 2) 部分保留
class C2<T1> extends Father<T1, Integer> {
 
  @Override
  public void test(Integer name) {
 
  }
}
 
// 不保留父類泛型 -----》子類按需實現
// 1)具體類型
class C3 extends Father<String, Integer> {
 
  @Override
  public void test(Integer name) {
 
  }
}
 
// 2)沒有具體類型
// 泛型擦除:實現或繼承父類的子類,沒有指定類型,相似於Object
class C4 extends Father {
 
  @Override
  public void test(Object name) {
 
  }
 
}


/**
 * 泛型擦除
 * 相似於Object,不等於Object
 * @author Administrator
 *
 */
public class Demo03 {
  
  public static void test(Student<Integer> student){
    student.setJavase(100);
  }
  
  public static void main(String[] args) {
    // 泛型擦除
    Student student = new Student();
    test(student);
    
    Student<Object> student2 = new Student<Object>();
    //test(student2);  //編譯異常
  }
 
}

通配符

通配符(Wildcards)ui

  • T、K、V、E 等泛型字母爲有類型,類型參數賦予具體的值
  • ?未知類型 類型參數賦予不肯定值,任意類型
  • 只能用在聲明類型、方法參數上,不能用在定義泛型類上
/**
 * 泛型的通配符 類型不肯定,用於聲明變量或者形參上面
 *
 * 不能使用在類上 或者  new 建立對象上
 * @author Administrator
 *
 */
public class Demo04 {
 
  // 用在形參上
  public static void test(List<?> list) {
 
   List<?> list2; // 用在聲明變量上
   list2 = new ArrayList<String>();
   list2 = new ArrayList<Integer>();
   list2 = new ArrayList<Object>();
 
  }
 
  public static void main(String[] args) {
   test(new ArrayList<String>());
   test(new ArrayList<Integer>());
  }
 
}

extends/super

上限(extends)

指定的類必須是繼承某個類,或者實現了某個接口(不是implements),即<=this

  • ? extends List

下限(super)

即父類或自己code

  • ? super List

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

/**
 * extends:泛型的上限 <= 通常用於限制操做 不能使用在添加數據上,通常都是用於數據的讀取
 *
 * supper:泛型的上限 >= 即父類或自身。通常用於下限操做
 *
 * @author Administrator
 * @param <T>
 */
 
public class Test<T extends Fruit> {
 
  private static void test01() {
    Test<Fruit> t1 = new Test<Fruit>();
    Test<Apple> t2 = new Test<Apple>();
    Test<Pear> t3 = new Test<Pear>();
  }
 
  private static void test02(List<? extends Fruit> list) {
 
  }
 
  private static void test03(List<? super Apple> list) {
 
  }
 
  public static void main(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,因此不能放入
  }
 
}
 
class Fruit {
 
}
 
class Apple extends Fruit {
 
}
 
class Pear extends Fruit {
 
}
 
class ReadApple extends Apple {
 
}

泛型嵌套

從外向裏取

import java.util.Map.Entry;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
 
/**
 * 泛型嵌套
 * @author Administrator
 *
 */
public class Demo05 {
 
  
  public static void main(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());
    }
    
  }
}


public class School<T> {
  private T stu;
 
  public T getStu() {
    return stu;
  }
 
  public void setStu(T stu) {
    this.stu = stu;
  }
  
}


public class Student2<T> {
  T score;
 
  public T getScore() {
    return score;
  }
 
  public void setScore(T score) {
    this.score = score;
  }
}

其餘

import java.util.ArrayList;
import java.util.List;
 
/**
 * 泛型沒有多態
 * 泛型沒有數組
 * JDK1.7對泛型的簡化
 * @author Administrator
 *
 */
public class Demo06 {
 
  public static void main(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<>();
  }
}
相關文章
相關標籤/搜索