拓冰建站拓冰建站
首页 / 资讯中心 / 正文

P08 · ClassCastException:类型强转翻车,Integer 变不成 String

P08 · ClassCastException类型强转翻车Integer 变不成 String场景还原一段从老项目继承来的代码用原始类型 List装数据为了省事没写泛型。后来你接手把它当成ListString用——结果运行时炸了java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String编译的时候好好的一运行就崩。这正是泛型擦除给你埋的雷编译期检查的类型安全到了运行期变成了信不信由你。一、问题现象注: CastDemo.java使用了未经检查或不安全的操作。 ← 编译时就警告你了 第一个元素: 你好 Exception in thread main java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader bootstrap) at CastDemo.main(CastDemo.java:14)二、出错代码importjava.util.*;publicclassCastDemo{publicstaticvoidmain(String[]args){ListStringlistnewArrayList();// 老代码 / 反射 / JSON 反序列化里容易混入原始类型用法Listrawlist;// 原生类型 List没写泛型raw.add(你好);raw.add(123);// ❌ 往以为是 String的列表里塞了 IntegerStringfirstlist.get(0);// 没问题你好本来就能转成 StringSystem.out.println(第一个元素: first);Stringsecondlist.get(1);// ← 这里炸了Integer 无法强转成 StringSystem.out.println(第二个元素: second);}}三、为什么会这样核心原因一句话Java 的泛型在运行期会被擦除。ListString list里的String只在编译期起作用——编译器用它做类型检查往里面 add 一个 Integer 在编译期会被拦住。但编译成字节码后这个类型信息就没了运行期的List就是一个什么都能装的桶。于是这段代码干了这么件事先用原生类型List raw list绕过了编译期检查成功把Integer 123塞了进去运行期list.get(1)返回的其实是Object指向 Integer 123代码里声明了String second ...JVM 在赋值时悄悄插入了强转(String)一个 Integer 怎么可能变成 String→ClassCastException。谁最常踩这个坑老代码 / 历史遗留的原始类型集合JSON 反序列化Gson/Jackson 没指定泛型时反序列化出的 List 里元素类型不可信取出来强转随时炸反射调用返回 Object 后随手强转泛型与继承混用ListString不是ListObject的子类这类问题。四、怎么解决原则让类型从源头就干净别把类型安全寄托在运行期的强转上。方案一杜绝原始类型全程写泛型ListStringlistnewArrayList();list.add(你好);// list.add(123); // ✅ 编译期直接报错根本活不到运行期方案二从不可信来源JSON/反射取数据时先校验再强转Objectobjmap.get(age);// JSON 解析出来的 Objectif(objinstanceofInteger){// ✅ 先 instanceof 判断intage(Integer)obj;}else{// 类型不对走兜底/报错而不是直接崩溃System.out.println(age 字段类型不是数字: obj);}方案三JSON 反序列化一定带上明确的泛型// GsonTypeToken 保住泛型ListUserusersnewGson().fromJson(json,newTypeTokenListUser(){}.getType());// JacksonTypeReference 同理ListUserusers2objectMapper.readValue(json,newTypeReferenceListUser(){});五、防坑总结代码里出现裸 List/Map没泛型就是隐患尽早补上泛型编译器的未经检查的操作警告别忽略它是在提醒你这里类型不安全从 JSON/反射拿到 Object 先instanceof再强转集合别跨类型假设传递一个 List 被当两种类型用早晚出事强转失败看异常信息X cannot be cast to Y说的是 X 转不成 Y——去源头查谁把 X 塞进来的。下一篇P09 · 数字转换 NumberFormatException
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门