getClass()和instanceof()有啥不同,如何记忆
在 Java 中,getClass()
和 instanceof
都用于类型检查,但它们在语义和使用场景上有重要区别。以下是它们的对比和记忆技巧:
1. 核心区别
特性 | getClass() | instanceof |
---|---|---|
定义 | 返回对象的 实际运行时类 | 检查对象是否是 某个类或其子类的实例 |
继承关系 | 严格匹配类(不包括子类) | 包含继承链(父类/接口也返回true ) |
null 处理 | 抛 NullPointerException | 对 null 返回 false |
典型用途 | 需要精确类型匹配时(如 equals ) | 需要兼容父类或接口时(多态场景) |
2. 代码示例
场景:父子类关系
class Animal {}
class Dog extends Animal {}
Animal a = new Dog();
-
getClass()
:a.getClass() == Dog.class // true a.getClass() == Animal.class // false(严格匹配)
-
instanceof
:a instanceof Dog // true a instanceof Animal // true(包含父类)
3. 如何选择?
-
用
getClass()
当:-
需要 精确类型匹配(如重写
equals()
时) -
示例:
@Override public boolean equals(Object o) { if (o == null || o.getClass() != this.getClass()) return false; // ... }
-
-
用
instanceof
当:-
需要 兼容继承体系(如多态、接口实现)
-
示例:
if (shape instanceof Circle) { ((Circle) shape).draw(); }
-
4. 记忆技巧
-
getClass()
:-
记作 "显微镜" —— 精确观察对象的实际类。
-
口诀:"严格匹配,一丝不苟"。
-
-
instanceof
:-
记作 "家族族谱" —— 检查对象是否属于某个家族(包括父辈)。
-
口诀:"子承父业,一脉相承"。
-
5. 经典陷阱
// 错误用法:在 equals() 中用 instanceof 可能导致对称性破坏
class Point {
int x, y;
@Override
public boolean equals(Object o) {
if (!(o instanceof Point)) return false; // ❌ 子类可能通过此检查
Point p = (Point) o;
return x == p.x && y == p.y;
}
}
class ColorPoint extends Point {
Color color;
@Override
public boolean equals(Object o) {
if (!(o instanceof ColorPoint)) return false;
ColorPoint cp = (ColorPoint) o;
return super.equals(o) && color.equals(cp.color);
}
}
// 测试:
Point p = new Point(1, 2);
ColorPoint cp = new ColorPoint(1, 2, RED);
p.equals(cp); // true(违反对称性!)
cp.equals(p); // false
解决方法:在需要严格相等时用 getClass()
代替 instanceof
。
总结
-
getClass()
:精确的"身份证"比对。 -
instanceof
:模糊的"家族关系"认证。 -
根据场景选择,尤其在重写
equals()
时要谨慎!