簡體   English   中英

Java泛型—尋找一種方法來告訴我泛型的超類型

[英]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.

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