簡體   English   中英

在Java中使用Generic返回類型調用方法

[英]Method call with Generic return type in Java

在C ++中,您可以在參數中指定函數的返回類型,例如:

C ++

    float* myFloat = CollectionClass.ptr<float>();
    int*   myInt   = CollectionClass.ptr<int>();

Java中是否有等價物來指定返回類型而不添加額外的類args?

Java的

    //This doesn't work (due to type erasure) 
    public <T> T getDate() 
    {
        if (T instanceof Date)
            return new Date();
        if (T instanceof Calendar)
            return new Calendar();
    }

    Date myDate = getDate<Date>();

使用簽名public <T> T getDate()聲明一個方法是完全正常的。

但是,無法實現返回所需內容的方法。 方法在運行時的作用不能僅依賴於它的類型參數,因為它不知道它的類型參數。

為了獲得對此的直覺,請認識到使用泛型編寫的任何代碼也可以在不使用泛型的情況下等效編寫,只需刪除泛型參數並在適當的位置插入強制轉換。 這就是“類型擦除”的含義。

因此,要想看看你的方法是否可以在泛型中使用,只需問一下,如果沒有泛型,你會怎么做:

public Object getDate() 
{
    // what would you do here?
}

Date myDate = (Date)getDate();

如果沒有Generics就無法做到,那么你也無法使用Generics。

C ++模板完全不同。 對於模板化函數和類,C ++模板為與其一起使用的每個類型參數生成函數或類的“單獨副本”。 即編譯器獲取模板化代碼並將其“復制並粘貼”到多個版本中,每個版本都是獨立的。 因此,代碼的每個副本都特定於某個類型參數,因此可以在運行時使用該類型。

這就是為什么C ++模板化代碼需要以源代碼形式提供才能使用它 - 沒有“編譯”模板這樣的東西。 但是,在Java中,可以使用編譯的泛型類。 Java中的通用類和方法不會假設它們可以使用的類型。

好的,現在通過編輯清楚地表明代碼是以T為條件的......

不,在Java中沒有任何簡單的方法可以實現這一功能 - 由於類型擦除,正如您的問題所提到的那樣。 你可以傳入Class<T>

public <T> T getDate(Class<T> clazz)
{
    // Now use clazz to work out what to do
}

...但是你不能做任何依賴於T本身在執行時的“價值”的事情 ,因為那是根本不知道的。 不幸的是,遺傳學在Java中有些貧血:(


編輯:在編輯之前使代碼以T為條件...

這只是以不同方式指定類型參數的問題:

import java.util.Date;

class Test {

    public static <T> T getDate() {
        return (T) new Date();
    }

    public <T> T getDateInstanceMethod() {
        return (T) new Date();
    }

    public static void main (String [] args) {
        Date date = Test.<Date>getDate();

        // Compiles fine, but is obviously bogus.
        String string = Test.<String>getDate();

        // And specifying a type argument for an instance method
        Test test = new Test();
        date = test.<Date>getDate();
    }
}

我總是更喜歡“在常規參數之前放置類型參數”的方法,但是我們去...

編輯:正如rgettman指出的那樣,類型推斷無論如何都會為你做正確的事情,因此在很多情況下你實際上並不需要指定類型參數。 有時你會這樣做。

使用Arrays.asList ,有時需要指定返回類型。 Java試圖根據所有參數的常見超類來“縮小”返回類型,但有時您需要特定類型。 例如,

List<Number> list = Arrays.asList(1, 2, 3);

這里, Arrays.asList返回List<Integer>並且您得到編譯器錯誤。 要使其返回List<Number> ,必須指定泛型類型。

List<Number> list = Arrays.<Number>asList(1, 2, 3);

暫無
暫無

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

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