@(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(); } }
命名泛型字母能夠隨意指定,儘可能使用單個的大寫字母(有時候多個泛型類型時會加上數字,好比T1,T2)
常見字母(見名知意)測試
/** * 自定義泛型類 * * 定義"模版"的時候,泛型用泛型字母: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
/** * 泛型的通配符 類型不肯定,用於聲明變量或者形參上面 * * 不能使用在類上 或者 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>()); } }
指定的類必須是繼承某個類,或者實現了某個接口(不是implements),即<=this
即父類或自己code
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<>(); } }