簡體   English   中英

如何正確指定班級 <?> 使用泛型的參數

[英]How to properly specify a Class<?> parameter using Generics

我的目標是實現一個接受類實例的操作,但前提是具體傳遞的類繼承自Collection。

我在無法解決的代碼上收到編譯器警告。

package com.fun.with.generics;

import java.util.ArrayList;
import java.util.Collection;

public class AcceptTypedClass
{
    // Warning here on 'Collection': ... raw type, references should be parameterized.
    private static void printCollectionClass( Class<? extends Collection> c )
    {
        System.out.println( c.getName() );
    }

    public static void main( String[] args )
    {
        // Warning here on ArrayList: ... raw type, references should be parameterized.
        Class<ArrayList> arrayList = ArrayList.class;
        printCollectionClass( arrayList );
    }
}

我確實理解警告消息,但是如果我通過添加缺少的類型參數(如下所示)來修復警告,則會出現錯誤。

Class<ArrayList<?>> arrayList = ArrayList.class;

有人可以解釋一下嗎? 問題是我是否可以編寫上面的代碼,以便沒有任何警告(並且該代碼有效)?

從根本上來說,類是作為通用“類型標記”的錯誤選擇,即在運行時指示某種特定類型的某些方法,因為在運行時沒有可用的通用類型信息。

最好使用以下任一方法:

  • 類的實例(例如,適當類型的空列表)-盡管這僅滿足類型安全性的編譯器,但未提供任何運行時類型信息。
  • 實際的“類型令牌”類,例如GSON的TypeTokenGuice的TypeLiteral

    請注意,這兩個類的Javadoc以以下內容開頭:

    表示通用類型T。Java尚未提供表示通用類型的方法,因此此類可以。 ...

    通過創建TypeToken的匿名子類來創建GSON類型令牌:

     TypeToken<ArrayList<String>> typeToken = new TypeToken<ArrayList<String>>() {}; 

    子類化操作通過typeToken.getClass().getGenericSuperclass()將泛型類型信息烘焙到typeToken實例中。

    請注意,但是您不能通用地執行此操作-您必須使用實際類作為通用參數而不是類型變量來創建子類。

您可以將printCollectionClass方法更改為

private static <T extends Collection<?>> void printCollectionClass(Class<T> c) {
        System.out.println(c.getName());
    }
public static void main(String[] args) {
        printCollectionClass(ArrayList.class);
    }

在這里, printCollectionClass將接受從collection繼承的類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM