使用括号的java泛型转换
我试图理解下一件事。下一步将打印此块代码
example.TestGenerics$One@49c2faae
example.TestGenerics$Two@20ad9418
所以我假设cast已经成功完成,但我希望列表中的第二个对象使用ClassCastException
public class TestGenerics
{
public static void main(String[] args)
{
Generic<One> integerGeneric = new Generic<One>(new Container(Lists.<Object>newArrayList(new One(), new Two())));
integerGeneric.checkContainer();
}
static class Generic<T>
{
private Container container;
public Generic(Container container)
{
this.container = container;
}
public void checkContainer()
{
for (Object key : container.getObjects())
{
final T genericKey = (T)key;
System.out.println(genericKey);
}
}
}
static class Container
{
Iterable<Object> objects;
public Container(Iterable<Object> objects)
{
this.objects = objects;
}
public Iterable<Object> getObjects()
{
return objects;
}
}
static class One
{
}
static class Two
{
}
}
附言。 我还面临一个问题,泛型类型转换(使用(T)对象)返回null而不是抛出异常ClassCastException,但我无法重现它。如果有人知道这一点,请在这里发表评论
# 1 楼答案
不一定是
Object
。这就是无界泛型的情况,就像在代码中一样。如果它有一个绑定,比如<T extends ParentClass>
,那么运行时类型将是ParentClass
。因为您的代码没有绑定,所以它将是Object
,这在强制转换期间不会引起任何问题现在,为了改进类型检查并获得正确的编译器错误,需要将泛型类型添加到
Container
:和更新
Generic
以避免使用原始Container
类:现在在主方法中添加一个diamond operator,以:
然后您将有:
以及一个编译器错误,指出如果所需类型为
One
,则不允许使用Lists.newArrayList(new One(), new Two())
顺便说一句:您仍然可以通过使用原始类型或
Object
作为泛型类型来绕过此编译器检查,这仍然不会导致运行时异常,因为Container
和Generic
类都没有边界