前端开发入门到精通的在线学习网站

网站首页 > 资源文章 正文

Java修炼终极指南:51. 一言以蔽之:使用instanceof进行类型检查

qiguaw 2024-10-08 06:50:53 资源文章 16 ℃ 0 评论


假设我们有一个对象(o)和一个类型(t),我们可以使用instanceof操作符通过编写o instanceof t来测试o是否为t类型。这是一个布尔操作符,对于确保后续强制类型转换操作的成功非常有用。例如,检查以下代码:

interface Furniture {};
class Plywood {};
class Wardrobe extends Plywood implements Furniture {};


当我们对对象(例如Wardrobe)与类型本身进行测试时,instanceof返回true:

Wardrobe wardrobe = new Wardrobe();
if(wardrobe instanceof Wardrobe) { } // true
Plywood plywood = new Plywood();
if(plywood instanceof Plywood) { } // true


如果被测试的对象(例如Wardrobe)是类型(例如Plywood)的子类的一个实例,instanceof返回true:

Wardrobe wardrobe = new Wardrobe();
if(wardrobe instanceof Plywood) {} // true


如果被测试的对象(例如Wardrobe)实现了由类型(例如Furniture)表示的接口,instanceof返回true:

Wardrobe wardrobe = new Wardrobe();
if(wardrobe instanceof Furniture) {} // true


基于此,我们可以说:

instanceof背后的逻辑依赖于IS-A关系(这在《Java完全编码面试指南》第6章“什么是继承?”中有详细说明)。一言以蔽之,这种关系基于接口实现或类继承。例如,wardrobe instanceof Plywood返回true,因为Wardrobe扩展了Plywood,所以Wardrobe是Plywood的一个实例。同样,Wardrobe也是一个Furniture的实例。另一方面,Plywood不是Furniture的一个实例,所以plywood instanceof Furniture返回false。在这个上下文中,由于每个Java类都扩展了Object,我们知道只要foo是Java类的一个实例,foo instanceof Object就返回true。此外,null instanceof Object(或任何其他对象)返回false,所以这个操作符不需要显式的空检查。

最后,请记住,instanceof只适用于具体化类型(在运行时具体化类型信息是可用的),这包括:

- 原始类型(int, float)

- 原始类型(List, Set)

- 非泛型类/接口(String)

- 具有无界通配符的泛型类型(List <?>, Map<?, ?>)

- 具体化类型的数组(String[], Map<?, ?>[], Set<?>[])

这意味着我们不能使用instanceof操作符(或强制类型转换)与参数化类型,因为类型擦除改变了泛型代码中的所有类型参数,所以我们无法在运行时说出泛型类型使用了哪个参数化类型。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表