我有一個參數化類型A<T extends B>
,另一個C<T2 extends A>
。訪問類型參數的參數化類型
是否有可能(靜態地)參考T
亞類從內部C
而無需添加T
作爲C
第二類型參數?目標是在返回類型爲T
的C
中添加方法。
想我寫:
class A<T extends B> {
}
class C<T2 extends A<T>> {
T myMethod() {
}
}
我有一個參數化類型A<T extends B>
,另一個C<T2 extends A>
。訪問類型參數的參數化類型
是否有可能(靜態地)參考T
亞類從內部C
而無需添加T
作爲C
第二類型參數?目標是在返回類型爲T
的C
中添加方法。
想我寫:
class A<T extends B> {
}
class C<T2 extends A<T>> {
T myMethod() {
}
}
就目前情況來看,你已經在你的C
定義中使用A
原始類型:
C<T2 extends A>
這是一個壞主意,並且你不能期望在這個上下文中獲得關於類型參數的信息,因爲你沒有指定任何類型參數。沒有找到T
。
在A
的定義中,類型T
只是一個參數。在您將特定的A
作爲參數使用特定的類別之前,T
不會引用任何內容。當你定義C
時,你必須說明你正在擴展的A
的味道,換句話說,指定一個真正的類型。
你在做什麼有點像詢問x
的值在f(x) = x+1
。直到你用一些特定的參數調用f
,x
只是一個標籤。
爲什麼這是一個壞主意?什麼會是一個更好的主意?有什麼不同的定義或類層次結構可以訪問T嗎? – Agos 2014-10-07 10:48:40
@Agos我試圖進一步解釋。 – 2014-10-07 10:56:58
這個答案不符合標準。從任何給定的T2實例中,都會有正好滿足一個T的邊界。但是Java的類型推斷並不試圖追蹤這樣的函數依賴關係。我認爲在擦除的情況下不可能實施,但我會留給Smutje解釋。 – 2014-10-07 15:44:56
A type variable is introduced by the declaration of a type parameter of
a generic class, interface, method, or constructor.
的T
在右的extends
的發生是一種類型的變量,而不是一個類型參數。如果你想用它作爲變量,它需要是範圍內的一個參數。
您可以添加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() {
...
}
}
...
}
我想答案是肯定的,就可以了,間接的影響。
我想你不能直接做,因爲類型擦除。 正如其他人已經提到,你將不得不添加另一個參數,或類型參數或嵌套類。
您可以將其間接使用泛型函數的組合做,從類的調用程序幫助,並從基類幫助:
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();
}
}
該解決方案似乎不太有用。你能回到C領域以外的東西嗎?一般來說'myMethod'可能比這更復雜。你能寫一個有T型參數的方法嗎? – 2014-10-08 05:48:49
當然,你可以寫一些像
不,因爲泛型不是「接口」的一部分,在編譯時擦除。 – Smutje 2014-10-07 10:40:21
@Smutje我說的是靜態訪問它們,而不是在運行時。 – Agos 2014-10-07 10:41:38
你能舉出你想寫什麼的例子代碼嗎? – 2014-10-07 10:42:57