簡體   English   中英

為什么我不能將類型參數顯式傳遞給通用 Java 方法?

[英]Why can't I explicitly pass the type argument to a generic Java method?

我定義了一個 Java 函數:

static <T> List<T> createEmptyList() {
    return new ArrayList<T>();
}

調用它的一種方法是這樣的:

List<Integer> myList = createEmptyList(); // Compiles

為什么我不能通過顯式傳遞泛型類型參數來調用它?

Object myObject = createEmtpyList<Integer>(); // Doesn't compile. Why?

我從編譯器收到錯誤Illegal start of expression

當java編譯器無法為靜態方法自己推斷參數類型時,您始終可以使用完全限定的方法名稱傳遞它:Class。 <Type> method();

Object list = Collections.<String> emptyList();

如果將類型作為方法參數傳入,則可以。

static <T> List<T> createEmptyList( Class<T> type ) {
  return new ArrayList<T>();
}

@Test
public void createStringList() {
  List<String> stringList = createEmptyList( String.class );
}

方法不能以與類型相同的方式進行泛化,因此具有動態類型泛型返回類型的方法的唯一選項 - phew是滿口的:-) - 是將類型作為參數傳遞。

有關Java泛型的真正優秀常見問題, 請參閱Angelika Langer的泛型常見問題解答


跟進:

在此上下文中使用Collection.toArray( T[] )的數組參數是沒有意義的。 在那里使用數組的唯一原因是因為使用相同的(預分配的)數組來包含結果(如果數組足夠大以使它們全部適合)。 這節省了在運行時始終分配新陣列的過程。

但是,出於教育目的,如果您確實想要使用數組類型,則語法非常相似:

static <T> List<T> createEmptyList( T[] array ) {
  return new ArrayList<T>();
}

@Test
public void testThing() {
  List<Integer> integerList = createEmptyList( new Integer[ 1 ] );
}

自從我挖掘Java的那些部分以來已經有一段時間了,但......

為什么你不能這樣做可能是語言開發人員的設計選擇。 盡管如此,由於Java使用的類型擦除 ,泛型信息無論如何都會在編譯時被刪除,因此在您的示例中,無論您是否具有類型參數,它都將創建完全相同的字節代碼。

@pauldoo是的,你是對的。 這是java泛型imho的弱點之一。

我對Cheekysoft的回應我想建議看一下Java人員自己如何做,比如T [] AbstractCollection#toArray (T [] a)。 我認為Cheekysofts版本更優越,但Java版本具有熟悉的優勢。

編輯:添加鏈接。 重新編輯:在SO上發現了一個bug :)


關於Cheekysoft的后續行動:嗯,因為它是應該返回的某種類型的列表,相應的示例應該類似於:

static <T> List<T> createEmptyList( List<T> a ) {
  return new ArrayList<T>();
}

但是,傳遞類對象顯然是更好的。 我唯一的論點就是熟悉,而在這個確切的例子中它並不值得(事實上它很糟糕)。

暫無
暫無

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

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