Java 泛型:比较 Object o 和 <E> 的类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/51582/
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
Java Generics: Comparing the class of Object o to <E>
提问by SCdF
Let's say I have the following class:
假设我有以下课程:
public class Test<E> {
public boolean sameClassAs(Object o) {
// TODO help!
}
}
How would I check that o
is the same class as E
?
我将如何检查o
与E
?
Test<String> test = new Test<String>();
test.sameClassAs("a string"); // returns true;
test.sameClassAs(4); // returns false;
I can't change the method signature from (Object o)
as I'm overridding a superclass and so don't get to choose my method signature.
我无法更改方法签名,(Object o)
因为我正在覆盖超类,因此无法选择我的方法签名。
I would also rather not go down the road of attempting a cast and then catching the resulting exception if it fails.
我也宁愿不尝试强制转换,然后在失败时捕获由此产生的异常。
采纳答案by Tom Hawtin - tackline
An instance of Test
has no information as to what E
is at runtime. So, you need to pass a Class<E>
to the constructor of Test.
的实例Test
没有关于E
运行时什么的信息。因此,您需要将 a 传递Class<E>
给 Test 的构造函数。
public class Test<E> {
private final Class<E> clazz;
public Test(Class<E> clazz) {
if (clazz == null) {
throw new NullPointerException();
}
this.clazz = clazz;
}
// To make things easier on clients:
public static <T> Test<T> create(Class<T> clazz) {
return new Test<T>(clazz);
}
public boolean sameClassAs(Object o) {
return o != null && o.getClass() == clazz;
}
}
If you want an "instanceof" relationship, use Class.isAssignableFrom
instead of the Class
comparison. Note, E
will need to be a non-generic type, for the same reason Test
needs the Class
object.
如果您想要“instanceof”关系,请使用Class.isAssignableFrom
而不是Class
比较。注意,E
将需要是非泛型类型,出于同样的原因Test
需要Class
对象。
For examples in the Java API, see java.util.Collections.checkedSet
and similar.
有关 Java API 中的示例,请参阅java.util.Collections.checkedSet
和类似内容。
回答by Slartibartfast
I could only make it working like this:
我只能让它像这样工作:
public class Test<E> {
private E e;
public void setE(E e) {
this.e = e;
}
public boolean sameClassAs(Object o) {
return (o.getClass().equals(e.getClass()));
}
public boolean sameClassAs2(Object o) {
return e.getClass().isInstance(o);
}
}
回答by Nick Fortescue
The method I've always used is below. It is a pain and a bit ugly, but I haven't found a better one. You have to pass the class type through on construction, as when Generics are compiled class information is lost.
我一直使用的方法如下。这是一种痛苦,有点难看,但我还没有找到更好的。您必须在构造时传递类类型,因为编译泛型时类信息会丢失。
public class Test<E> {
private Class<E> clazz;
public Test(Class<E> clazz) {
this.clazz = clazz;
}
public boolean sameClassAs(Object o) {
return this.clazz.isInstance(o);
}
}
回答by Ayman
I was just trying to do the same thing, and one neat trick i just realized is that you can can try a cast, and if the cast fails, ClassCastException will be thrown. You can can catch that, and do whatever.
我只是想做同样的事情,我刚刚意识到的一个巧妙技巧是您可以尝试强制转换,如果强制转换失败,将抛出 ClassCastException。你可以抓住它,做任何事情。
so your sameClassAs method should look like:
所以你的 sameClassAs 方法应该是这样的:
public boolean sameClassAs(Object o) {
boolean same = false;
try {
E t = (E)o;
same = true;
} catch (ClassCastException e) {
// same is false, nothing else to do
} finally {
return same;
}
}