Java集合接口(例如,List
或Set
)定义了接受任何对象的contains
方法。检查泛型类型
public boolean contains(Object o)
然而,当涉及到实施这种方法,我工作特别的收藏需要,我有一种类型是与类的泛型类型E
(即或者是E级,或兼容E的子类,或者如果E是接口,则实现E的类)。换句话说,如果o可铸造成E型,那么它是兼容的。这就提出一个问题,因为Java擦除泛型类型的信息,所以这样的事情是不可能的:
public boolean contains(Object o)
{
if(o instanceof E) // compile error due to type erasures
{
// ... check if this collection contains o
}
return false;
}
我的问题是什么是完成这样的事情的最好方法? Oracle Article on Type Erasures提到这是禁止的,但不提供任何解决此问题的方法。
我只能想到一个半优雅的方式来解决这个问题:
做强制转换为类型E.如果转换失败,邻类型不能为E或类型的子类E.
public boolean contains(Object o)
{
try
{
E key = (E) o; // I know it's unsafe, but if o is castable to E then the method should work
// check if this collection contains key
}
catch(ClassCastException e)
{
// invalid type, cannot contain o
}
return false;
}
虽然这会工作,但看起来很乱(我不喜欢以这种方式使用例外)。
有没有更好的方法来实现这个相同的目标(改变方法签名是不允许的)?
编辑:是的,这不起作用由于E被擦除对象:(
它工作吗?你会得到一个未经检查的铸造编译器警告。你永远不会得到一个ClassCastException(除非'o'不是'E'的**擦除**的实例,可能是'Object')。 –
您能否详细说明“要求我有一个与类的泛型E兼容的类型?”谢谢。 –
我同意 - 这是行不通的。你确实需要实际的类做适当的演员,可能会失败。 –
StaxMan