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("这货不是字符串!"); }
??划重点??:
- instanceof左边写对象,右边写类型
- 不仅检查对象本身类型,还认祖宗(继承链上的父类都算)
- ??特别注意??:不能用于基本数据类型(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
??对比表格??收好不谢:
instanceof | getClass() | |
---|---|---|
继承关系 | ?? 包含父类 | ?? 只认本尊 |
接口判断 | ?? 有效 | ?? 无效 |
性能 | 快(编译时检查) | 较快(运行时检查) |
使用场景 | 类型安全验证 | 精确类型匹配 |
这时候肯定有好奇宝宝要问:那如果我拿到的是个泛型对象怎么办?比如说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];
虽然反射看起来很酷炫,但是??新手必看警告??:
- 性能开销较大(别在循环里乱用)
- 代码可读性会下降(慎用!)
- 需要处理各种异常(NoSuchMethodException之类的)
举个真实案例:上次我帮学弟改代码,他死活查不出从数据库拿回来的Blob字段类型。最后用反射一查,好家伙,数据库驱动返回的居然是个自定义的BinaryStream对象!
个人血泪经验谈
用了这么多年Java,我总结出个规律:??能用instanceof解决的绝对不用反射??!特别是新手阶段,千万别被反射的花哨功能迷惑。就像我家楼下王大爷说的:"杀鸡用牛刀,迟早要挨刀"
什么时候该用getClass()呢?比如说在做对象深拷贝的时候,必须精确知道具体类型。上次有个同事用instanceof判断List类型,结果拷贝出来的ArrayList变成了LinkedList,整个缓存系统直接崩了...(别问,问就是加班改bug)
还有个小窍门分享给大家:??善用IDE的调试功能??!在Debug模式下,直接把鼠标悬停在变量上就能看到实时类型,比写代码判断快多了。不过考试时可不能用这招啊!(别问我怎么知道的)
最后说句掏心窝子的话:类型判断就像谈恋爱,??别猜来猜去,直接验明正身最靠谱??!下次再遇到类型不明的对象,就把这三板斧轮着使一遍。记住咱们的黄金准则——简单场景用instanceof,精确匹配用getClass,遇到妖魔鬼怪再请反射大法!
本文由嘻道妙招独家原创,未经允许,严禁转载