![](/img/trans.png)
[英]Supertype casting in generics (Getting the generic supertype of a generic type)
[英]Java generics — looking for a method to tell me the supertype of a generic type
的超類型
SomeClass <Double>
是
Someclass <T extends Numbers>
而且不是
SomeClass <Numbers>
我正在尋找一種返回泛型類實例的超類型的方法。 Class
getGenericSuperclass()
之Class
(雖然不能完全一樣getGenericSuperclass()
僅返回一個類,而泛型可以擴展並受多個限制,如下所示:
例如。:
Someclass <T extends aConcreteClass && anInterface && anotherInterface>
當我在泛型類的實例上運行getGenericSuperclass()
時,我得到了Object
作為回報。
Java中是否有這樣的方法可以告訴我實例化對象的泛型的超類型?
// ===================
編輯:冗長的評論@jwa的答案如下:
我了解泛型是在編譯時進行類型檢查的。 但是,JVM仍然可以在運行時綁定類型,特別是使用類型推斷的結果,並且至少返回超類型的定義,而不僅僅是返回Object作為超類型。 該信息顯然在運行時可用。 但我知道它沒有這樣做。
注意:尚未深入研究類型擦除。
// =================================
EDIT2:
引用此頁面中的“綁定類型參數”一詞,我一直在尋找一種方法來返回對象的“綁定類”,
在示例中是可比的
public class Node<T extends Comparable<T>> {
private T data;
private Node<T> next;
public Node(T data, Node<T> next) {
this.data = data;
this.next = next;
}
public T getData() { return data; }
// ...
}
在同一頁面上 。
在那些頁面或其他任何地方都找不到它-我想Java不會這么做。
您需要查看“類型擦除”。 本質上,當您將Java代碼編譯為字節碼時,通用信息會丟失(或“擦除”)。 這就是為什么您找不到通過反射類查詢通用類型的任何方法的原因。
我在SO上找不到有關類型擦除的好答案,但Wikiepdia似乎有一個合理的描述 。
值得注意的是,選擇類型擦除是為了在Java 1.5和1.4之間提供向后兼容性。 其他語言對此的實現方式也有所不同。 例如,.NET完全支持字節碼中的泛型-並且確實允許此類方法作為其反射API的一部分。
考慮此類,該類使用類型化和非類型化列表:
import java.util.List;
public class CastExample <T extends Object> {
public List<T> typedList;
public List<?> untypedList;
public T getFirstElement() {
return typedList.get(0);
}
public T getFromUntypedArray() {
return (T) untypedList.get(0);
}
}
兩種方法以字節碼進行編碼的方式之間沒有區別。 我們可以使用javap
,特別是javap -c CastExample
:
/var/tmp-> javap -c CastExample
Compiled from "CastExample.java"
public class CastExample<T> {
public java.util.List<T> typedList;
public java.util.List<?> untypedList;
public CastExample();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public T getFirstElement();
Code:
0: aload_0
1: getfield #2 // Field typedList:Ljava/util/List;
4: iconst_0
5: invokeinterface #3, 2 // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
10: areturn
public T getFromUntypedArray();
Code:
0: aload_0
1: getfield #4 // Field untypedList:Ljava/util/List;
4: iconst_0
5: invokeinterface #3, 2 // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
10: areturn
}
這些操作中每個操作的確切含義都不過分重要。 重要的是它調用的是完全相同的操作,兩者之間沒有區別。
的超類型
SomeClass
<Double>
是Someclass
<T extends Numbers>
問題的前提是錯誤的。 首先, Someclass <T extends Numbers>
在Java上在語法上不正確。
其次,沒有一個類型的單個泛型“超類型”。 以下是SomeClass <Double>
的某些(但不是全部)超類型的SomeClass <Double>
:
SomeClass<? extends Number>
SomeClass<? extends Serializable>
SomeClass<? extends Comparable<Double>>
SomeClass<? extends Comparable<? extends Number>>
SomeClass<? extends Comparable<? extends Serializable>>
SomeClass<? extends Comparable<? extends Comparable<Double>>>
SomeClass<? extends Comparable<?>>
SomeClass<? extends Object>
SomeClass<?>
SomeClass<? super Double>
Object
(and if SomeClass has a superclass or interface SuperclassOfSomeClass:)
SuperclassOfSomeClass<Double>
SuperclassOfSomeClass<? extends Number>
... (all of the above for SomeClass repeated for SuperclassOfSomeClass, etc.)
是的,泛型在Java中不是協變的,即List <Number>不是List <Double>的超類。 您應該閱讀一些相關信息,這里是一個鏈接 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.