1. 主页 > 好文章

Java判断对象类型的3种常用方法,新手必学技巧

你是不是经常在写Java代码的时候,突然卡壳不知道手里的对象到底是啥类型?比如说从别人那接了个参数,看着像是字符串,结果一运行就给你报个ClassCastException?别慌,今天咱们就来唠唠这个让新手头疼的问题——??怎么判断Java对象的真实身份??!

先给大家吃颗定心丸:这个问题其实就跟查身份证似的,Java早就给我们准备好了三把钥匙。咱们先从一个最接地气的场景说起:你从网上扒拉下来一段JSON数据,转成Object之后,咋确定它是不是你心心念念的那个User对象?


第一把钥匙:instanceof运算符(简单粗暴型)

java复制
Object obj = new ArrayList<>();
if(obj instanceof String) {
    System.out.println("这是字符串!");
} else {
    System.out.println("这货不是字符串!");
}

??划重点??:

  1. instanceof左边写对象,右边写类型
  2. 不仅检查对象本身类型,还认祖宗(继承链上的父类都算)
  3. ??特别注意??:不能用于基本数据类型(int、char这些)

有同学可能要问:那如果我想精确匹配怎么办?比如说ArrayList和List的关系,用instanceof判断List会返回true啊!这就是咱们要说的第二把钥匙的用武之地了。


第二把钥匙:getClass()方法(精确到毫米)

java复制
Object obj = new ArrayList<>();
System.out.println(obj.getClass() == ArrayList.class); // true
System.out.println(obj.getClass() == List.class);    // false

??对比表格??收好不谢:

instanceofgetClass()
继承关系?? 包含父类?? 只认本尊
接口判断?? 有效?? 无效
性能快(编译时检查)较快(运行时检查)
使用场景类型安全验证精确类型匹配

这时候肯定有好奇宝宝要问:那如果我拿到的是个泛型对象怎么办?比如说List这种?这时候咱们的终极大招就要登场了。


第三把钥匙:反射机制(无所不能型)

java复制
Object obj = new HashMap<>();
Class<?> clazz = obj.getClass();

// 检查是否实现Map接口
boolean isMap = clazz.isAssignableFrom(Map.class);
// 检查实际泛型类型(这个要复杂些)
Type genericType = ((ParameterizedType)obj.getClass().getGenericSuperclass()).getActualTypeArguments()[0];

虽然反射看起来很酷炫,但是??新手必看警告??:

  1. 性能开销较大(别在循环里乱用)
  2. 代码可读性会下降(慎用!)
  3. 需要处理各种异常(NoSuchMethodException之类的)

举个真实案例:上次我帮学弟改代码,他死活查不出从数据库拿回来的Blob字段类型。最后用反射一查,好家伙,数据库驱动返回的居然是个自定义的BinaryStream对象!


个人血泪经验谈

用了这么多年Java,我总结出个规律:??能用instanceof解决的绝对不用反射??!特别是新手阶段,千万别被反射的花哨功能迷惑。就像我家楼下王大爷说的:"杀鸡用牛刀,迟早要挨刀"

什么时候该用getClass()呢?比如说在做对象深拷贝的时候,必须精确知道具体类型。上次有个同事用instanceof判断List类型,结果拷贝出来的ArrayList变成了LinkedList,整个缓存系统直接崩了...(别问,问就是加班改bug)

还有个小窍门分享给大家:??善用IDE的调试功能??!在Debug模式下,直接把鼠标悬停在变量上就能看到实时类型,比写代码判断快多了。不过考试时可不能用这招啊!(别问我怎么知道的)


最后说句掏心窝子的话:类型判断就像谈恋爱,??别猜来猜去,直接验明正身最靠谱??!下次再遇到类型不明的对象,就把这三板斧轮着使一遍。记住咱们的黄金准则——简单场景用instanceof,精确匹配用getClass,遇到妖魔鬼怪再请反射大法!

本文由嘻道妙招独家原创,未经允许,严禁转载