我试图理解接下来的事情。接下来将打印此 block 代码
example.TestGenerics$One@49c2faae
example.TestGenerics$Two@20ad9418
所以我认为转换已成功完成,但我希望列表中的第二个对象出现 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)object)返回 null 而不是抛出异常 ClassCastException 的问题,但我无法重现它。如果有人知道这件事,请在这里发表评论
最佳答案
I have learned that JVM see generic like Object type in runtime (or nearest type, if it has "exists")
不一定Object
.无限泛型就是这种情况,就像在您的代码中一样。如果它有界限,比如 <T extends ParentClass>
,则运行时类型将为 ParentClass
.由于您的代码没有限制,它将是 Object
这不会在 Actor 阵容中造成任何问题。
现在,为了改进类型检查并获得正确的编译器错误,您需要将通用类型添加到 Container
:
static class Container<T> {
Iterable<T> objects;
public Container(Iterable<T> objects) {
this.objects = objects;
}
public Iterable<T> getObjects() {
return objects;
}
}
并更新Generic
避免使用原始 Container
类:
static class Generic<T> {
private Container<T> container;
public Generic(Container<T> container) {
this.container = container;
}
public void checkContainer() {
for (T key : container.getObjects()) {
final T genericKey = key;
System.out.println(genericKey);
}
}
}
现在添加一个diamond operator在你的主要方法中:
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())));
编译器错误表明Lists.newArrayList(new One(), new Two())
如果所需类型为 One
,则不允许.
顺便说一句:您仍然可以通过使用原始类型或 Object
来绕过此编译器检查。作为通用类型,这仍然不会导致运行时异常,因为 Container
和 Generic
类没有界限。
关于java - 使用括号的通用转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36498368/