Blog 泛型

import java.lang.reflect.ParameterizedType;
import java.util.Arrays;

public class Ans {
    public static void main(String[] args) {
        test3();
        test6();
    }

    static void test0() {
        //對於List<Inter>不能轉型爲List<Number>有一個理解,如果可以這麼做轉型後就可以add(new Float(0))這明顯不合適
    }

    static void test3() {
        //在泛型中無法得到類型參數,但是如果有一個類繼承了含有確定類型參數的泛型,則可以從這個類得到父類的類型參數,因爲如果這時還沒有任何父類類型參數的信息,子類就不知道自己可以保存什麼樣的數據
        class A<T> {}
        class AInt extends A<Integer> {}

        System.out.println(Arrays.toString(A.class.getTypeParameters()));       //這裏的T只是個名字,毫無意義

        System.out.println(AInt.class.getGenericSuperclass().getTypeName());    //這是類型參數的類名
        System.out.println(Arrays.toString(((ParameterizedType) AInt.class.getGenericSuperclass()).getActualTypeArguments()));      //這是這個類的class對象
    }

    static void test4() {
        class A<T> {
            void a(A<? extends T> a,T t) {}                       //對於這種傳參的一個優勢是可以保證a在方法中無法調用a.set(anything)這種方法,即限制了a的行爲,當然一個例外是a.set(null),這個可以使用,但多是情況下是無意義的
        }
    }

    static void test5() {
        //同樣的super也是爲了限制一些行爲
        //無界通配符<?>的一個特點:A<?>可以接受一切A<>或A的向上轉型,而且它也可以限制很多操作
        //而且使用無界通配A<?>符代替無通配符A的一個好處是可以將一些不合適的由警告變成編譯時報錯
    }

    static void test6() {
        class B {}
        B []b = pickTwo(new B(),new B());
    }
    static <K> K[] pickTwo(K k1,K k2) {
        K []k = (K [])asArray(k1,k2);                   //這裏必須要轉型
        K []k0 = asArray2(k1,k2);                       
        //! return (K [])asArray(k1,k2);                //這兩個都是classCastException,由於這個K[]不能傳遞到外界
        //! return asArray2(k1,k2);
        return null;
    }
    static Object[] asArray(Object o1,Object o2) {return new Object[]{o1,o2};}
    static <T> T[] asArray2(T...objs) {return objs;}
}

class A<T> {
    //! public boolean equals(T obj) {return super.equals(obj); }               //這樣不行,因爲T被擦除爲Object,這樣就與Object.equals有相同的參數所以這不是一個重載,而這個表示又不是重寫

    static void test2() {
        //泛型類中的靜態方法不能使用類中的泛型參數,在下面我們可以看到方法可以含有泛型類型,但是這個T已經與類型中的T無關了,最好改一下名稱
    }
    //! static void a(T t){}
    static <T> void a(T t) {}                           //這個T和類中的T無關,建議改成別的名字(如下)
    static <K> void b(K k) {}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章