java 如何将对象实例的类型与泛型类型进行比较?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6029974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to compare type of an object's instance to a generic type?
提问by Adibe7
how can i write this code in java?
我如何用java编写这段代码?
public class ComponentsManager
{
private List<IComponent> list = new ArrayList<IComponent>();
public <U extends IComponent> U GetComponent() {
for (IComponent component : list) {
if(component instanceof U)
{
return component;
}
}
}
}
but i cant perform instanceof on generic types. how should i do it? thanks.
但我无法对泛型类型执行 instanceof。我该怎么做?谢谢。
回答by Stephen C
Basically you can't do that due to type erasure. The normal workaround is to pass a Class
object as a parameter; e.g.
由于类型擦除,基本上你不能这样做。正常的解决方法是将Class
对象作为参数传递;例如
public <U extends IComponent> U GetComponent(Class<U> clazz) {
for (IComponent component : list) {
if (clazz.isInstance(component)) {
return clazz.cast(component);
}
}
}
You could also use if (clazz.equals(component.getClass())) { ...
but that does an exact type match ... which is not what the instanceof
operator does. The instanceof
operator and the Class.instanceOf
method both test to see if the value's type is assignment compatible.
你也可以使用if (clazz.equals(component.getClass())) { ...
但它确实是一个精确的类型匹配......这不是instanceof
运算符所做的。在instanceof
运营商和Class.instanceOf
方法都测试,看看如果值的类型是赋值兼容。
回答by Hosam Aly
As far as I know, you can't. You'll have to take a Class
object as a parameter:
据我所知,你不能。您必须将Class
对象作为参数:
public <U extends IComponent> U getComponent(Class<U> clazz) {
// ...
if (component.getClass() == clazz) {
return (U) component;
}
}
And call it like this:
并这样称呼它:
getComponent(MyComponentImpl.class);
回答by Andreas Dolk
General rule with java - if a generic class needs to know its generic type(s), then you have to pass a hint. A common approach for the problem is using the constructor:
java的一般规则 - 如果一个泛型类需要知道它的泛型类型,那么你必须传递一个提示。该问题的常见方法是使用构造函数:
public class ComponentsManager<U extends IComponent> {
private Class<U extends IComponentManeger> genericType = null;
public ComponentsManager<U extends IComponent>(
Class<U extends IComponent> genericType) {
this.genericType = genericType;
}
}
Now the class knows it's generic type class and you can uses the generic type class instance to verify, if a component in your collection matches the classes generic type.
现在该类知道它是泛型类,您可以使用泛型类实例来验证集合中的组件是否与类泛型类型匹配。
回答by sje397
You could try adding a couple of 'test' methods:
您可以尝试添加几个“测试”方法:
private static <U extends IComponent> boolean testComponent(U u) {
return true;
}
private static boolean testComponent(Object o) {
return false;
}
Then, use testComponent(component)
instead of component instanceof U
.
然后,使用testComponent(component)
代替component instanceof U
。
Example code:
示例代码:
import java.util.*;
class IComponent {
}
class T1 extends IComponent {
}
public class Test {
public static <U extends IComponent> boolean testComponent(U u) {
return true;
}
public static boolean testComponent(Object o) {
return false;
}
public static void main(String[] args) {
T1 t = new T1();
System.out.println("hm? " + (testComponent(t) ? "true" : "false"));
}
}
Output:
输出:
hm? true
嗯?真的
回答by u3758939
Exactly generic type can't be treated as a normal variable in code, which makes it hard to do comparing directly. However the reflective class, ParameterizedType
, could help you get an instance representing a parameterized type, which is basically practicable objects.
完全泛型类型在代码中不能被视为普通变量,这使得很难直接进行比较。然而,反射类ParameterizedType
可以帮助您获得一个表示参数化类型的实例,它基本上是可行的对象。
Type genericSuperType = object.getClass().getGenericSuperclass()
Type[] actualTypeParams = ((ParameterizedType) genericSuperType).getActualTypeArguments()
if (actualTypeParams[0] instanceof Class) {
((Class) actualTypeParams[0]).isInstance(testingObj);
}
For more details about the usage upon ParameterizedType
and corresponding TypeVariable
, the internal util class, TypeParameterMatcher`, in Nettycould be referenced.
更多的使用ParameterizedType
和对应TypeVariable
的细节,可以参考Netty中的内部util类TypeParameterMatcher`。