簡體   English   中英

Java:帶有類型參數的泛型類型?

[英]Java : generic type with type parameters?

我有一個像這樣的 class :

public class MyClass <T extends Model1, X extends Model2> {

    private CommonMessage<T,X> someMethod() {
        ....
    }
}

現在我有一個自定義的消息類型MyMessage extends CommonMessage ,所以我想知道如何擁有仍然具有 T 和 X 作為參數的泛型類型? 例如:

public class MyClass <M extends CommonMessage, T extends Model1, X extends Model2> {

    private M<T,X> someMethod() {
        ....
    }
}

簡短的回答:

首先,由於CommonMessage是通用的,以非通用方式擴展它是非常糟糕的,所以你應該做M extends CommonMessage<T, X>並且這種方式因為在 class 聲明中傳遞給 CommonMessage 的類型參數你不應該提到這個參數在方法返回類型處再次鍵入,因此方法返回類型應為 M。

長答案:

我知道您確實知道這些定義,但有時我們作為人類會忘記簡單的事情。 首先我們應該考慮創建 generics 是為了什么,使用 generics 我們可以創建具有不同參數類型的類,當它們被另一個 class 擴展時會提供這些參數類型,或者當我們使用 new() 運算符創建它們時我們正在編寫我們的 class 我們不知道這些參數的確切類型,我們希望將這個決定推遲到以后,這與您在 class 中所做的事情相矛盾,因為這里您的方法是私有的,您無法更改它在您的子類中實現(從您的類繼承的 class)。 但是要知道我們可以將您的實現更改為這樣的東西,這樣可以很好地編譯:

public  class MyClass<M extends CommonMessage<T, X>, T extends Model1, X extends Model2> {
    private  M method1(){
        ...
    }
}

public class CommonMessage<T, X>{

}

public class MyMessage<T, X> extends CommonMessage<T, X>{

}
public class Model1{

}
public class Model2{

}

盡管此實現將被編譯,但問題是當您編寫私有方法(method1)時,您在編寫此 class 時不知道 M 的類型是什么,因為它將在我們想要創建新實例時傳遞這個 class 或當我們從這個 class 繼承另一個 class 時。 那么你想在你的方法1中創建並返回什么類型的Object? 您在這里唯一知道的是它的類型是 M,它擴展了 CommonMessage,但是在編寫私有方法(方法 1)時您不知道 M 的確切類型是什么!

最重要的是,您不能將此決定委托給您的子類(因為此方法是私有的)。 現在的問題是,當我們不知道 M 的確切類型時,為什么它被允許並編譯得很好? 暫時忘記這個問題,我會在解釋正確的方法后說清楚。 那么正確的方法是什么? 想想看,編寫子類的人確實知道參數 M 的類型是什么,他們可以在方法 1 的實現中創建適當的 M 實例以從該方法返回。 那么為什么不把這個決定委托給子類並使這個方法抽象呢? 這完全有道理。 簡而言之,我們有一些這樣的實現:

public abstract  class MyClass<M extends CommonMessage<T, X>, T extends Model1, X extends Model2> {
    public abstract M method1();
}

public class CommonMessage<T, X>{

}

public class MyMessage<T, X> extends CommonMessage<T, X>{

}
public class Model1{

}
public class Model2{

}

現在讓我們回到我們的問題,為什么我建議給你的第一個程序編譯得很好? 為什么我們被允許擁有其返回類型是通用的私有方法,該方法將在實例化或 inheritance 時間傳遞? 因為有很多情況使它正確和適當。 一種情況是我們的私有方法調用另一個返回適當類型的公共方法,如下所示:

public abstract class MyClass<M extends CommonMessage<T, X>, T extends Model1, X extends Model2> {
    private  M method1(){
        return method2();
    }
     abstract M method2();
}

public class CommonMessage<T, X>{

}

public class MyMessage<T, X> extends CommonMessage<T, X>{

}
public class Model1{

}
public class Model2{

}

暫無
暫無

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

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