Java泛型:将对象o类与<;E>;
假设我有以下课程:Java泛型:将对象o类与<;E>;,java,generics,Java,Generics,假设我有以下课程: public class Test<E> { public boolean sameClassAs(Object o) { // TODO help! } } 我无法从(Object o)更改方法签名,因为我正在重写一个超类,因此无法选择我的方法签名 我也不希望尝试强制转换,然后在失败时捕获生成的异常。我只能让它这样工作: public class Test<E> { private E e;
public class Test<E> {
public boolean sameClassAs(Object o) {
// TODO help!
}
}
我无法从(Object o)
更改方法签名,因为我正在重写一个超类,因此无法选择我的方法签名
我也不希望尝试强制转换,然后在失败时捕获生成的异常。我只能让它这样工作:
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);
}
}
公共类测试{
私人E;
公共无效集(E){
这个。e=e;
}
公共布尔sameClassAs(对象o){
返回(o.getClass().equals(e.getClass());
}
公共布尔sameclassa2(对象o){
返回e.getClass().isInstance(o);
}
}
下面是我一直使用的方法。这是一个痛苦和有点丑陋,但我还没有找到一个更好的。您必须在构造时传递类类型,就像编译泛型时丢失类信息一样
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);
}
}
公共类测试{
私人课堂;
公开考试(课堂){
this.clazz=clazz;
}
公共布尔sameClassAs(对象o){
返回此.clazz.isInstance(o);
}
}
测试的实例没有关于运行时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(clazz==null){
抛出新的NullPointerException();
}
this.clazz=clazz;
}
//要使客户的工作更轻松,请执行以下操作:
公共静态测试创建(类clazz){
返回新测试(clazz);
}
公共布尔sameClassAs(对象o){
返回o!=null&&o.getClass()==clazz;
}
}
如果需要“instanceof”关系,请使用Class.isAssignableFrom
而不是Class
比较。注意,E
必须是非泛型类型,原因与Test
需要Class
对象相同
有关Java API中的示例,请参见Java.util.Collections.checkedSet
和类似内容。我只是想做同样的事情,我刚刚意识到的一个巧妙的技巧是,您可以尝试强制转换,如果强制转换失败,将抛出ClassCastException。你可以抓住它,做任何事
因此,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;
}
}
不会的。这是一个未经检查的演员阵容。它永远不会抛出异常。在运行时,“t”的擦除类型为E,这只是对象,所以并没有执行强制转换。您是正确的。这将节省我以后大量的疑难解答,因为编译似乎很好。我宁愿将这些类与equals进行比较。或者使用==?有特殊原因吗?它们是等价的。IMO==更容易阅读(尽管它确实意味着读者必须知道类型)。在内联之前,速度稍微快一点。现在,我似乎没有测试过的是一个空的clazz。
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;
}
}