[英]How can I force two instance variables to be of the same generic type?
假設我有一個包含泛型類型的兩個實例變量的類,我該如何強制這些類型相同?
我沒有在其他地方找到任何類似的問題(更不用說答案了),這可能是因為我使用了錯誤的術語。 有這個問題 ,但我不確定如何將它應用到我的情況。
簡而言之,如何才能使最后一行代碼無法編譯?
class Foo<T> {
private T value;
}
class Bar {
private Foo var1;
private Foo var2;
public Bar(Foo var1, Foo var2) {
this.var1 = var1;
this.var2 = var2;
}
public static void main(String[] args) {
Foo<String> var1 = new Foo<>();
Foo<Integer> var2 = new Foo<>();
Bar b = new Bar(var1, var2); // this should not work
}
}
Make Bar
也是通用的:
class Bar<T> {
private Foo<T> var1;
private Foo<T> var2;
public Bar(Foo<T> var1, Foo<T> var2) {
this.var1 = var1;
this.var2 = var2;
}
public static void main(String[] args) {
Foo<String> var1 = new Foo<>();
Foo<Integer> var2 = new Foo<>();
Bar<String> b = new Bar<>(var1, var2); // this does not work
}
}
通過使用類級別泛型參數T
for Bar
您可以為兩個實例變量強制實施相同的類型。
這也消除了@daniu在評論中提到的使用原始類型( 永遠不應該使用 )的警告。
現在,如果您碰巧不使用原始類型但希望允許不同類型,則可以使用通配符:
使用上限,只允許鍵入讀取( var1
和var2
將始終生成類型為T
的實現):
class Bar<T> {
private Foo<? extends T> var1;
private Foo<? extends T> var2;
public Bar(Foo<? extends T> var1, Foo<? extends T> var2) {
this.var1 = var1;
this.var2 = var2;
}
public static void main(String[] args) {
Foo<String> var1 = new Foo<>();
Foo<Integer> var2 = new Foo<>();
Bar<Object> b = new Bar<>(var1, var2); // this does now work
}
}
並且具有較低的有界,只允許類型化寫入( var1
和var2
將始終使用類型T
任何實現):
class Bar<T> {
private Foo<? super T> var1;
private Foo<? super T> var2;
public Bar(Foo<? super T> var1, Foo<? super T> var2) {
this.var1 = var1;
this.var2 = var2;
}
public static void main(String[] args) {
Foo<Integer> var1 = new Foo<>();
Foo<Number> var2 = new Foo<>();
Bar<Integer> b = new Bar<>(var1, var2); // this does now work
}
}
有關該主題的更多信息,您可以閱讀: 什么是PECS(Producer擴展消費者超級)?
Lino的答案很好。 我想補充一個事實:
如果您不必跟蹤var
的類型,但只驗證它們的類型相同,那么您可以將類型參數從Bar
類移動到其構造函數:
class Bar {
// These will always have the same type, but
// that's not visible here
private Foo<?> var1;
private Foo<?> var2;
// The parameter types of the construct ensures that
// the vars are always of the same type
public <T> Bar(Foo<T> var1, Foo<T> var2) {
this.var1 = var1;
this.var2 = var2;
}
public static void main(String[] args) {
Foo<String> var1 = new Foo<>();
Foo<Integer> var2 = new Foo<>();
Bar b1 = new Bar(var1, var1); // Works fine
Bar b2 = new Bar(var1, var2); // Compilation error
}
}
這種技術適用於各種方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.