I would expect that from the aspect of compile time as well as from the aspect of runtime it wouldn't be a problem for .getClass()
to provide a correctly-typed return value.
我希望从编译时间以及运行时方面来看,.getClass()提供正确类型的返回值不会有问题。
But I must be wrong.
但我一定是错的。
public class _GetClassGenerics2 {
static class MyClass {
}
public static void main(String[] args) {
MyClass myInstance = new MyClass();
// here it works
Class<? extends MyClass> type = myInstance.getClass();
myMethod(myInstance);
}
public static <T extends MyClass> void myMethod(T instance) {
Class<? extends T> type = instance.getClass();
// java.lang.RuntimeException: Uncompilable source code - incompatible types
// required: java.lang.Class<? extends T>
// found: java.lang.Class<capture#1 of ? extends _GetClassGenerics2.MyClass>
}
}
EDIT: It doesn't work with Class<T>
and Class<? super T>
either.
编辑:它不适用于Class
4 个解决方案
#1
4
As per the Javadoc of the getClass
method:
根据getClass方法的Javadoc:
The actual result type is
Class<? extends |X|>
where |X| is the erasure of the static type of the expression on whichgetClass
is called. For example, no cast is required in this code fragment实际的结果类型是Class <? extends | X |> where | X |是擦除调用getClass的表达式的静态类型。例如,此代码片段中不需要强制转换
Here, the value for |X|
in your code snippet is MyClass
, hence instance.getClass()
is assignable to only Class<? extends MyClass>
or Class<?>
.
这里,| X |的值在你的代码片段中是MyClass,因此instance.getClass()只能分配给Class <?扩展MyClass>或Class <?>。
The reason for this specific wording is because when you say that for this variable having type T where <T extends MyClass>
, there can be multiple classes which extend MyClass
and hence capable of satisfying the T extends MyClass
criteria. Without runtime information there is no way of knowing which concrete implementation subclass of MyClass
was passed in the method. Hence to provide a generic solution, it returns <? extends MyClass>
since that would hold true for any subclass of MyClass
irrespective of what class instance is passed in.
这个特定措辞的原因是因为当你说这个变量有类型T,其中
#2
6
java.lang.Class
does not represent a type (use java.lang.reflect.Type
for that). If T
, were say ArrayList<String>
then it makes no sense for there to be a Class<ArrayList<String>>
.
java.lang.Class不表示类型(使用java.lang.reflect.Type)。如果是T,那么说ArrayList
It's worth noting that in this particular case there is no need for the method to be generic.
值得注意的是,在这种特殊情况下,该方法不需要是通用的。
public static <T extends MyClass> void myMethod(T instance) {
Is equivalent to:
相当于:
public static void myMethod(MyClass instance) {
#3
0
Instead of
代替
Class<? extends T> type = instance.getClass();
you need to use
你需要使用
Class<? extends MyClass> type = instance.getClass();
You cannot directly use the T
here.
你不能在这里直接使用T.
The reason is the method signature of Object.getClass()
(which you are invoking). It's:
原因是Object.getClass()的方法签名(您正在调用它)。它的:
public final Class<? extends Object> getClass()
So you are trying to convert from Class<? extends Object>
to Class<? extends T>
, which is not allowed (because you are down-casting). It is allowed using an explicit cast:
所以你试图从Class <?将Object>扩展为Class <?扩展T>,这是不允许的(因为你是向下的)。允许使用显式强制转换:
Class<? extends T> type = (Class<? extends T>) instance.getClass();
will work (though it generates a type safety warning).
将起作用(虽然它会产生类型安全警告)。
#4
0
Java does not support a generic type of <this> e.g.
Java不支持通用类型的
Object could implement
对象可以实现
class Object {
Class<this> getClass()
}
But there is no way for getClass() to express that it will return a type which is the class of the object. The compiler has no native understand of what this method does either.
但getClass()无法表达它将返回一个类型,该类型是对象的类。编译器没有本机了解此方法的功能。
IMHO, This behaviour should have been supported.
恕我直言,应该支持此行为。
#1
4
As per the Javadoc of the getClass
method:
根据getClass方法的Javadoc:
The actual result type is
Class<? extends |X|>
where |X| is the erasure of the static type of the expression on whichgetClass
is called. For example, no cast is required in this code fragment实际的结果类型是Class <? extends | X |> where | X |是擦除调用getClass的表达式的静态类型。例如,此代码片段中不需要强制转换
Here, the value for |X|
in your code snippet is MyClass
, hence instance.getClass()
is assignable to only Class<? extends MyClass>
or Class<?>
.
这里,| X |的值在你的代码片段中是MyClass,因此instance.getClass()只能分配给Class <?扩展MyClass>或Class <?>。
The reason for this specific wording is because when you say that for this variable having type T where <T extends MyClass>
, there can be multiple classes which extend MyClass
and hence capable of satisfying the T extends MyClass
criteria. Without runtime information there is no way of knowing which concrete implementation subclass of MyClass
was passed in the method. Hence to provide a generic solution, it returns <? extends MyClass>
since that would hold true for any subclass of MyClass
irrespective of what class instance is passed in.
这个特定措辞的原因是因为当你说这个变量有类型T,其中
#2
6
java.lang.Class
does not represent a type (use java.lang.reflect.Type
for that). If T
, were say ArrayList<String>
then it makes no sense for there to be a Class<ArrayList<String>>
.
java.lang.Class不表示类型(使用java.lang.reflect.Type)。如果是T,那么说ArrayList
It's worth noting that in this particular case there is no need for the method to be generic.
值得注意的是,在这种特殊情况下,该方法不需要是通用的。
public static <T extends MyClass> void myMethod(T instance) {
Is equivalent to:
相当于:
public static void myMethod(MyClass instance) {
#3
0
Instead of
代替
Class<? extends T> type = instance.getClass();
you need to use
你需要使用
Class<? extends MyClass> type = instance.getClass();
You cannot directly use the T
here.
你不能在这里直接使用T.
The reason is the method signature of Object.getClass()
(which you are invoking). It's:
原因是Object.getClass()的方法签名(您正在调用它)。它的:
public final Class<? extends Object> getClass()
So you are trying to convert from Class<? extends Object>
to Class<? extends T>
, which is not allowed (because you are down-casting). It is allowed using an explicit cast:
所以你试图从Class <?将Object>扩展为Class <?扩展T>,这是不允许的(因为你是向下的)。允许使用显式强制转换:
Class<? extends T> type = (Class<? extends T>) instance.getClass();
will work (though it generates a type safety warning).
将起作用(虽然它会产生类型安全警告)。
#4
0
Java does not support a generic type of <this> e.g.
Java不支持通用类型的
Object could implement
对象可以实现
class Object {
Class<this> getClass()
}
But there is no way for getClass() to express that it will return a type which is the class of the object. The compiler has no native understand of what this method does either.
但getClass()无法表达它将返回一个类型,该类型是对象的类。编译器没有本机了解此方法的功能。
IMHO, This behaviour should have been supported.
恕我直言,应该支持此行为。