当声明指向特定类型实例的类类型变量时,对象类型由实例化而不是声明确定。例如:
Object o = new ArrayList<>();
if(o instanceof ArrayList)
System.out.println("ArrayList it is!");
因此,ArrayList只能使用Object的方法和属性,在这种情况下,即使我向下转换它。如何将ArrayList仅部分实现,如果将类型设为Object,它会不会更有意义?
另外,为什么可以在没有通用声明的情况下使用钻石推理?
答案 0 :(得分:2)
如果你和我通过电话交谈,那么你只与我的声音接触,但这并不意味着我的其余部分不再存在。您正在将该ArrayList作为Object连接,但它仍然包含ArrayList的所有部分 - 您只是没有与其他部分连接。
答案 1 :(得分:1)
Object O = new ArrayList<>();
这个特殊代码说; “创建类型为o
的引用变量Object
,并将其指向堆上创建的新ArrayList<>
对象。”
当jvm运行代码时,将检查instanceof
条件。即使引用变量的类型为Object
,执行期间创建的实际对象也是ArrayList
对象。
如果您尝试使用ArrayList<>
引用变量Object
o
的任何属性/方法,请{g} o.size()
;
编译器会抛出错误。
答案 2 :(得分:0)
Java 7之前的空菱形是一个所谓的原始泛型,实际上它意味着容器不会对包含的项强制执行任何类型约束,除了它们应该是一个Object。所以基本上new ArrayList<>();
或new ArrayList();
表示new ArrayList<Object>();
。这基本上会抛弃Java泛型提供的任何类型安全性。
@scottb提醒我们:Java 7为空钻石提供了更好的用法:通过编译器执行类型推断,您的代码可以稍微更简单,更不容易出错。而不是HashMap<String, Integer> m = new HashMap<String, Integer>();
,您可以说HashMap<String, Integer> m = new HashMap<>();
。
对于第一部分:如果您使用java.lang.Object
变量引用ArrayList
对象,则o
是您感知instanceof
对象的类型。 o
运算符不关心o
的类型,它会准确回答您的问题:变量ArrayList
后面存储的东西是否真的是{{1}} {1}}或不。{/ p>