2014-10-07 113 views
1

我有一個參數化類型A<T extends B>,另一個C<T2 extends A>訪問類型參數的參數化類型

是否有可能(靜態地)參考T亞類從內部C而無需添加T作爲C第二類型參數?目標是在返回類型爲TC中添加方法。

想我寫:

class A<T extends B> { 

} 

class C<T2 extends A<T>> { 
    T myMethod() { 

    } 
} 
+0

不,因爲泛型不是「接口」的一部分,在編譯時擦除。 – Smutje 2014-10-07 10:40:21

+0

@Smutje我說的是靜態訪問它們,而不是在運行時。 – Agos 2014-10-07 10:41:38

+0

你能舉出你想寫什麼的例子代碼嗎? – 2014-10-07 10:42:57

回答

2

就目前情況來看,你已經在你的C定義中使用A原始類型:

C<T2 extends A> 

這是一個壞主意,並且你不能期望在這個上下文中獲得關於類型參數的信息,因爲你沒有指定任何類型參數。沒有找到T

A的定義中,類型T只是一個參數。在您將特定的A作爲參數使用特定的類別之前,T不會引用任何內容。當你定義C時,你必須說明你正在擴展的A的味道,換句話說,指定一個真正的類型。

你在做什麼有點像詢問x的值在f(x) = x+1。直到你用一些特定的參數調用fx只是一個標籤。

+0

爲什麼這是一個壞主意?什麼會是一個更好的主意?有什麼不同的定義或類層次結構可以訪問T嗎? – Agos 2014-10-07 10:48:40

+0

@Agos我試圖進一步解釋。 – 2014-10-07 10:56:58

+0

這個答案不符合標準。從任何給定的T2實例中,都會有正好滿足一個T的邊界。但是Java的類型推斷並不試圖追蹤這樣的函數依賴關係。我認爲在擦除的情況下不可能實施,但我會留給Smutje解釋。 – 2014-10-07 15:44:56

0

section 4.4 of the spec

A type variable is introduced by the declaration of a type parameter of 
a generic class, interface, method, or constructor. 

Textends的發生是一種類型的變量,而不是一個類型參數。如果你想用它作爲變量,它需要是範圍內的一個參數。

您可以添加T作爲像這樣的參數:

class A<T extends B> { 
    ... 
} 

class C<T, T2 extends A<T>> { 
    T myMethod() { 
     ... 
    } 
} 

,但是這是你的問題是在逃避。另一種方法是使C一個內部類:

class A<T extends B> { 

    class C<T2 extends A<T>> { 
     T myMethod() { 
      ... 
     } 
    } 

    ... 
} 
0

我想答案是肯定的,就可以了,間接的影響。

我想你不能直接做,因爲類型擦除。 正如其他人已經提到,你將不得不添加另一個參數,或類型參數或嵌套類。

您可以將其間接使用泛型函數的組合做,從類的調用程序幫助,並從基類幫助:

class B 
{ 

} 

class B2 extends B // B2 is Just an example of a concrete type T 
{ 

} 

class A<T extends B> { 
    T t; 
    T getT() 
    { 
     return t; 
    } 
} 

class C<T2 extends A<?>> { 
    T2 t2; 

    T2 getT2() 
    { 
     return t2; 
    } 
    <X> X getValWithInnerType(A<? extends X> x) 
    { 
     return x.getT(); 
    } 

} 



public class Example { 

    public static void main(String[] args) { 
     C<A<B2>> c1 = new C<>(); 
     B2 inner = c1.getValWithInnerType(c1.getT2()); 

    } 
} 

如果你願意得到你想要的類型,但不一定是直接從C級,你也可以做一些簡單的使用組成:

class B 
{ 

} 

class B2 extends B 
{ 

} 

class A<T extends B> { 
    T t; 
    T getT() 
    { 
     return t; 
    } 
} 

class C<T2 extends A<?>> { 
    T2 t2; 
    T2 getT2() 
    { 
     return t2; 
    } 

} 



public class Example { 



    public static void main(String[] args) { 
     C<A<B2>> c1 = new C<>(); 
     B2 inner = c1.getT2().getT(); 

    } 
} 

最後,如果它不是關鍵,以得到確切的推導式T,你可以有一個函數返回B型:

class B 
{ 

} 

class B2 extends B 
{ 

} 

class A<T extends B> { 
    T t; 
    T getT() 
    { 
     return t; 
    } 
} 

class C<T2 extends A<? extends B>> { 
    T2 t2; 

    B getT2() 
    { 
     return t2.getT(); 
    } 


} 
+0

該解決方案似乎不太有用。你能回到C領域以外的東西嗎?一般來說'myMethod'可能比這更復雜。你能寫一個有T型參數的方法嗎? – 2014-10-08 05:48:49

+0

當然,你可以寫一些像 T getValWithInnerType(T x){return x; },但我認爲這不會有用,因爲除了該函數之外,您不能在類C中使用該T。 – 2014-10-08 10:26:55