从类型变量的部分访问,指向特定类型的实例

时间:2013-04-27 22:12:20

标签: java class inheritance interface casting

当声明指向特定类型实例的类类型变量时,对象类型由实例化而不是声明确定。例如:

Object o = new ArrayList<>();
if(o instanceof ArrayList)
System.out.println("ArrayList it is!");

因此,ArrayList只能使用Object的方法和属性,在这种情况下,即使我向下转换它。如何将ArrayList仅部分实现,如果将类型设为Object,它会不会更有意义?

另外,为什么可以在没有通用声明的情况下使用钻石推理?

3 个答案:

答案 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>