1. 程式人生 > >Java 泛型型別推斷注意之一

Java 泛型型別推斷注意之一

Java 在判斷泛型型別的時候,往往是在賦值操作的時候,能夠通過引數化類判斷出具體的型別。

如:

public class GenericMethods {
    public static <T> ArrayList<T> f(){
        return new ArrayList<T>();
    }
    public static void m(ArrayList<String> list){
        System.out.println(list.getClass().getName());
    }
    public static void main(String[] args){
        ArrayList<String> list = f();//通過泛型方法及型別推斷得到了list
        m(list);//m方法可以使用該list
<span style="white-space:pre">	</span>//m(f());   //m方法不可直接以f(泛型)方法的結果作為引數。
    }
}

f() 通過控制代碼中的<String>,得知了返回的ArrayList<T>中的T代表什麼型別。因此,m方法可以直接呼叫得到的list。

但是,如果用m方法直接呼叫f(),由於f不知道應返回什麼型別的ArrayList,因此預設為Object(T的基類),而m引數顯示地

以ArrayList<String>為引數,編譯器在此不會自動轉換,而是依然固執地往裡傳ArrayList<Object>,因此報錯。

這裡的編譯器永遠不會將Object轉換為String,即便是如下:

public class GenericMethods {
    public static ArrayList<String> f(){
        return new ArrayList<String>();
    }
    public static void m(ArrayList<Object> list){
        System.out.println(list.getClass().getName());
    }
    public static void main(String[] args){
        ArrayList<String> list = f();//通過泛型方法及型別推斷得到了list
       // m(list);//m方法不可以使用該list,編譯器指出,需要ArrayList<Object>而不是ArrayList<String>
       // m(f()); //同上
    }
}
通過上面這兩段程式碼得知,泛型方法獲得具體型別時,僅僅在賦值的時候有效。引數中不會自動轉換。

但是,如下面一段程式碼:

public class GenericMethods {
    public static String f(){
        return new String("this is a string");
    }
    public static void m(Object o){
        System.out.println(o.getClass());
    }
    public static void main(String[] args){
        m(f());//Object 自動轉為String,因為String是其子類。
    }
}

注意,不要將這兩種現象混淆。一種為泛型的賦值,一種為類的繼承的使用。