亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在Java中使用Class <T>?

如何在Java中使用Class <T>?

慕容森 2019-11-05 10:33:53
在這個問題上,對泛型及其背后的作用進行了很好的討論,因此我們都知道泛型Vector<int[]>是整數數組的向量,并且HashTable<String, Person>是一個表,其鍵是字符串和值Persons。但是,讓我感到困擾的是的用法Class<>。Java類Class應該也采用一個模板名稱,(否則,Eclipse中的黃色下劃線告訴我)。我不明白該放什么。在整點Class的對象是當你不完全具備有關對象的信息,進行反思和這樣的。為什么要讓我指定Class對象將容納哪個類?我顯然不知道,或者我不會使用該Class對象,而是使用特定的對象。
查看完整描述

3 回答

?
慕妹3146593

TA貢獻1820條經驗 獲得超9個贊

使用Class的通用版本,Class可以讓您編寫諸如


Class<? extends Collection> someCollectionClass = someMethod();

然后,您可以確保收到的Class對象擴展了Collection,并且該類的實例將(至少)是Collection。


查看完整回答
反對 回復 2019-11-05
?
largeQ

TA貢獻2039條經驗 獲得超8個贊

我們所知道的是“ 任何類的所有實例共享該類類型的相同java.lang.Class對象 ”


例如)


Student a = new Student();

Student b = new Student();

那a.getClass() == b.getClass()是真的。


現在假設


Teacher t = new Teacher();

沒有泛型,下面是可能的。


Class studentClassRef = t.getClass();

但這是錯誤的..?


例如)public void printStudentClassInfo(Class studentClassRef) {}可以用Teacher.class


使用泛型可以避免這種情況。


Class<Student> studentClassRef = t.getClass(); //Compilation error.

現在什么是T ?? T是類型參數(也稱為類型變量);用尖括號(<>)分隔,在類名之后。

T只是一個符號,就像在編寫類文件期間聲明的變量名(可以是任何名稱)一樣。稍后,

在初始化(HashMap<String> map = new HashMap<String>();)時將用有效的類名替換T


例如) class name<T1, T2, ..., Tn>


因此Class<T>表示特定類類型為' T' 的類對象。


假設您的類方法必須使用未知的類型參數,如下所示


/**

 * Generic version of the Car class.

 * @param <T> the type of the value

 */

public class Car<T> {

    // T stands for "Type"

    private T t;


    public void set(T t) { this.t = t; }

    public T get() { return t; }

}

在這里T可以String用作CarName的類型


OR T可以用作modelNumber的Integer類型,


OR T可以用作有效的汽車實例的Object類型。


現在,上面是簡單的POJO,可以在運行時以不同的方式使用它。

集合(例如List,Set,Hashmap)是最好的示例,它們將根據T的聲明與不同的對象一起工作,但是一旦我們將T聲明為String(

例如)HashMap<String> map = new HashMap<String>();,則它將僅接受String類實例對象。


通用方法


泛型方法是引入自己的類型參數的方法。這類似于聲明泛型類型,但是類型參數的范圍僅限于聲明它的方法。允許使用靜態和非靜態通用方法,以及通用類構造函數。


通用方法的語法包括類型參數,尖括號內,并且出現在方法的返回類型之前。對于泛型方法,類型參數部分必須出現在方法的返回類型之前。


 class Util {

    // Generic static method

    public static <K, V, Z, Y> boolean compare(Pair<K, V> p1, Pair<Z, Y> p2) {

        return p1.getKey().equals(p2.getKey()) &&

               p1.getValue().equals(p2.getValue());

    }

}


 class Pair<K, V> {


    private K key;

    private V value;

}

這<K, V, Z, Y>是方法參數中使用的類型聲明,該聲明應在boolean此處的返回類型之前。


在下面;<T>在方法級別不需要類型聲明,因為它已經在類級別聲明了。


class MyClass<T> {

   private  T myMethod(T a){

       return  a;

   }

}

但是下面是錯誤的,因為類級別的類型參數K,V,Z和Y不能在靜態上下文中使用(此處為靜態方法)。


class Util <K, V, Z, Y>{

    // Generic static method

    public static  boolean compare(Pair<K, V> p1, Pair<Z, Y> p2) {

        return p1.getKey().equals(p2.getKey()) &&

               p1.getValue().equals(p2.getValue());

    }

}

其他有效場景


class MyClass<T> {


        //Type declaration <T> already done at class level

        private  T myMethod(T a){

            return  a;

        }


        //<T> is overriding the T declared at Class level;

        //So There is no ClassCastException though a is not the type of T declared at MyClass<T>. 

        private <T> T myMethod1(Object a){

                return (T) a;

        }


        //Runtime ClassCastException will be thrown if a is not the type T (MyClass<T>).  

        private T myMethod1(Object a){

                return (T) a;

        }       


        // No ClassCastException        

        // MyClass<String> obj= new MyClass<String>();

        // obj.myMethod2(Integer.valueOf("1"));

        // Since type T is redefined at this method level.

        private <T> T myMethod2(T a){

            return  a;

        }


        // No ClassCastException for the below

        // MyClass<String> o= new MyClass<String>();

        // o.myMethod3(Integer.valueOf("1").getClass())

        // Since <T> is undefined within this method; 

        // And MyClass<T> don't have impact here

        private <T> T myMethod3(Class a){

            return (T) a;

        }


        // ClassCastException for o.myMethod3(Integer.valueOf("1").getClass())

        // Should be o.myMethod3(String.valueOf("1").getClass())

    private  T myMethod3(Class a){

        return (T) a;

    }



        // Class<T> a :: a is Class object of type T

        //<T> is overriding of class level type declaration; 

        private <T> Class<T> myMethod4(Class<T> a){

            return  a;

        }

    }

最后,靜態方法總是需要顯式<T>聲明。它不會從課堂上衍生出來Class<T>。這是因為類級別T與實例綁定。


查看完整回答
反對 回復 2019-11-05
?
慕婉清6462132

TA貢獻1804條經驗 獲得超2個贊

從Java文檔中:


[...]更令人驚訝的是,類Class已被泛化?,F在,類文字可以用作類型令牌,同時提供運行時和編譯時類型信息。這將啟用一種新的AnnotatedElement接口中的getAnnotation方法示例的靜態工廠樣式:


<T extends Annotation> T getAnnotation(Class<T> annotationType); 

這是一種通用方法。它從其參數推斷其類型參數T的值,并返回T的適當實例,如以下代碼段所示:


Author a = Othello.class.getAnnotation(Author.class);

在使用泛型之前,您必須將結果強制轉換為Author。另外,您將無法使編譯器檢查實際參數是否表示Annotation的子類。[...]


好吧,我從來沒有用過這種東西。任何人?


查看完整回答
反對 回復 2019-11-05
  • 3 回答
  • 0 關注
  • 6793 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號