[英]Java generics — looking for a method to tell me the supertype of a generic type
the supertype of 的超类型
SomeClass <Double>
is 是
Someclass <T extends Numbers>
and is not 而且不是
SomeClass <Numbers>
i'm looking for a method returning the supertype of an instance of a generic class. 我正在寻找一种返回泛型类实例的超类型的方法。 Something like
getGenericSuperclass()
of the of Class
( although can't be exactly like it-- getGenericSuperclass()
returns only one class while a generic can extend and be bounded by multiple as in: Class
getGenericSuperclass()
之Class
(虽然不能完全一样getGenericSuperclass()
仅返回一个类,而泛型可以扩展并受多个限制,如下所示:
Eg.: 例如。:
Someclass <T extends aConcreteClass && anInterface && anotherInterface>
When i run getGenericSuperclass()
on an instance of a generic class, i'm getting Object
in return. 当我在泛型类的实例上运行
getGenericSuperclass()
时,我得到了Object
作为回报。
Is there such a method anywhere in Java, telling me the supertype of the generic type on which i instantiated an object on? Java中是否有这样的方法可以告诉我实例化对象的泛型的超类型?
//=================== // ===================
EDIT: lengthy comment to @jwa's answer below: 编辑:冗长的评论@jwa的答案如下:
i understand the generics are type-checked at compile time. 我了解泛型是在编译时进行类型检查的。 however, JVM could still bind the types in run-time, as specifically as possible using the outcome of type inference , and return at least the definition of the supertype rather than merely returning Object as the supertype.
但是,JVM仍然可以在运行时绑定类型,特别是使用类型推断的结果,并且至少返回超类型的定义,而不仅仅是返回Object作为超类型。 This info is clearly available in runtime.
该信息显然在运行时可用。 but i gather it's not doing this.
但我知道它没有这样做。
NOTE: haven't yet looked deep into type erasure. 注意:尚未深入研究类型擦除。
//================================= // =================================
EDIT2: EDIT2:
referring to the term "bounded type parameter" in this page, i've been looking for a method to return the object's "bound class(es)", 引用此页面中的“绑定类型参数”一词,我一直在寻找一种方法来返回对象的“绑定类”,
which is Comparable in the example 在示例中是可比的
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; }
// ...
}
no trace of it in those pages or anywhere else-- i guess Java not doing it. 在那些页面或其他任何地方都找不到它-我想Java不会这么做。
You need to take a look into "type erasure". 您需要查看“类型擦除”。 Essentially, when your java code is compiled into bytecode the generic information is lost (or "erased").
本质上,当您将Java代码编译为字节码时,通用信息会丢失(或“擦除”)。 This is why you cannot find any methods for querying the generic typing via the reflection classes.
这就是为什么您找不到通过反射类查询通用类型的任何方法的原因。
I couldn't find a good answer regarding type erasure here on SO, but Wikiepdia seems to have a reasonable description . 我在SO上找不到有关类型擦除的好答案,但Wikiepdia似乎有一个合理的描述 。
It's worth noting that type erasure was chosen to give backward-compatability between java 1.5 and 1.4. 值得注意的是,选择类型擦除是为了在Java 1.5和1.4之间提供向后兼容性。 Other languages have implemented this differently.
其他语言对此的实现方式也有所不同。 For example, .NET has full support for generics in byte code - and does permit such methods as part of its reflection API.
例如,.NET完全支持字节码中的泛型-并且确实允许此类方法作为其反射API的一部分。
Consider this class, which uses typed and non-typed lists: 考虑此类,该类使用类型化和非类型化列表:
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);
}
}
There is no difference between the way that the two methods are encoded in byte code. 两种方法以字节码进行编码的方式之间没有区别。 We can see this using
javap
, specifically javap -c CastExample
: 我们可以使用
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
}
The exact meaning of each of these operations is not overly important. 这些操作中每个操作的确切含义都不过分重要。 The important thing is that it is calling the exact same operations, there's no distinction between the two.
重要的是它调用的是完全相同的操作,两者之间没有区别。
the supertype of
的超类型
SomeClass
<Double>
isSomeClass
<Double>
是Someclass
<T extends Numbers>
Someclass
<T extends Numbers>
The premise of the question is wrong. 问题的前提是错误的。 First of all,
Someclass <T extends Numbers>
is not syntactically correct as a type in Java. 首先,
Someclass <T extends Numbers>
在Java上在语法上不正确。
And second, there is no single generic "supertype" of a type. 其次,没有一个类型的单个泛型“超类型”。 The following is a list of some (but not all) supertypes of
SomeClass <Double>
: 以下是
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.)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.