Java 使用括号的泛型强制转换

Java 使用括号的泛型强制转换,java,generics,Java,Generics,我试图理解下一件事。下一步将打印此块代码 example.TestGenerics$One@49c2faae example.TestGenerics$Two@20ad9418 所以我假设cast已经成功完成,但我希望列表中的第二个对象使用ClassCastException public class TestGenerics { public static void main(String[] args) { Generic<One> intege

我试图理解下一件事。下一步将打印此块代码

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
    {

    }
}
附言。 此外,我还面临一个问题,即使用Tobject的泛型类型转换返回null,而不是抛出异常ClassCastException,但我无法重现它。如果有人知道这一点,请在这里发表评论

我已经了解到,JVM在运行时可以看到类似泛型的对象类型或最近的类型(如果存在的话)

不一定反对。这就是无界泛型的情况,就像在代码中一样。如果它有一个绑定,比如,那么运行时类型将是ParentClass。因为您的代码没有绑定,所以它将是对象,这在强制转换期间不会引起任何问题

现在,为了改进类型检查并获得正确的编译器错误,您需要向容器添加泛型类型:

现在在主方法中添加一个:

Generic<One> integerGeneric = new Generic<One>(new Container(Lists.<Object>newArrayList(new One(), new Two())));
然后您将有:

Generic<One> integerGeneric = new Generic<>(new Container<>(Lists.newArrayList(new One(), new Two())));
如果所需类型为1,则不允许使用Lists.newArrayListnew One、new Two的编译器错误

顺便说一句:您仍然可以通过使用原始类型或对象作为泛型类型来绕过编译器检查,这仍然不会导致运行时异常,因为容器类和泛型类都没有边界

我已经了解到,JVM在运行时可以看到类似泛型的对象类型或最近的类型(如果存在的话)

不一定反对。这就是无界泛型的情况,就像在代码中一样。如果它有一个绑定,比如,那么运行时类型将是ParentClass。因为您的代码没有绑定,所以它将是对象,这在强制转换期间不会引起任何问题

现在,为了改进类型检查并获得正确的编译器错误,您需要向容器添加泛型类型:

现在在主方法中添加一个:

Generic<One> integerGeneric = new Generic<One>(new Container(Lists.<Object>newArrayList(new One(), new Two())));
然后您将有:

Generic<One> integerGeneric = new Generic<>(new Container<>(Lists.newArrayList(new One(), new Two())));
如果所需类型为1,则不允许使用Lists.newArrayListnew One、new Two的编译器错误


顺便说一句:您仍然可以通过使用原始类型或对象作为泛型类型绕过此编译器检查,这仍然不会导致运行时异常,因为容器类和泛型类都没有界限。

您可能想查看什么是类型擦除,以及它在Java中的工作方式。我敢打赌,您在其中有一个未经检查的强制类型转换警告。@Tom,谢谢,我了解到JVM在运行时看到类似泛型的对象类型或最近的类型,如果它存在,您可能想查看擦除是什么类型以及它在Java中的工作方式。我敢打赌,您在其中有一个未经检查的强制转换警告。@Tom,谢谢,我了解到JVM在运行时会看到泛型,如对象类型或最近的类型,如果它存在,如果有人怀疑落选:用它作为他的报复落选的目标之一。如果有人怀疑落选:用它作为他的报复落选的目标之一。