char是基本类型占2字节,Character是包装类可为null、支持泛型;必须用Character的场景包括泛型集合、反射、空值语义;需注意自动装箱拆箱陷阱、缓存范围(0–127)、禁止用==比较、避免高频装箱影响性能。

char 是基本类型,Character 是它的包装类
Java 里 char 占 2 字节,直接存 Unicode 码点值;Character 是对象,有方法、能为 null、可放进集合或泛型容器。别把它俩当成“差不多的写法”——底层内存模型和使用边界完全不同。
什么时候必须用 Character 而不能用 char
遇到泛型、集合、反射或需要空值语义时,char 就不顶用了。比如 ArrayList<char></char> 编译不过,但 ArrayList<character></character> 没问题;又比如 JSON 反序列化字段可能为 null,用 char 接收会直接抛 NullPointerException。
-
Map<string character></string>可以存null值,Map<string char></string>根本不合法 -
Optional<character></character>有意义,Optional<char></char>编译失败 - 调用
Character.isLetter()这类静态工具方法时,参数是char,但你传Character也能自动拆箱——别反过来试,char没法直接调方法
自动装箱/拆箱带来的坑
看着方便,但容易在 == 判断和缓存范围上翻车。JVM 对 Character 值在 \u0000 到 \u007f(即 0–127)之间做了缓存,超出这个范围每次 new 都是新对象。
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
Character a = 'a'; // 自动装箱,命中缓存 Character b = 'a'; System.out.println(a == b); // true Character c = '\u0080'; // 超出缓存范围 Character d = '\u0080'; System.out.println(c == d); // false!得用 .equals() 比较
- 永远别用
==比较两个Character实例,除非你明确知道它们在缓存范围内且来自同一来源 - 方法参数是
char时,传Character会自动拆箱;但如果该Character是null,立刻抛NullPointerException - 高频循环里反复装箱(比如把
char[]转成List<character></character>)会触发大量对象分配,影响 GC
性能和内存开销的实际差异
单个 char 是 2 字节栈上值;单个 Character 至少占 16 字节(对象头 + 字段 + 对齐填充),还涉及堆分配和 GC 压力。差一个数量级不是夸张。
立即学习“Java免费学习笔记(深入)”;
- 数组场景优先用
char[],比如解析字符串、做字符计数、IO 缓冲区 - 只在必要时才升级到
Character:比如要存进Set<character></character>去重,或作为 Map 的 key(注意char本身不能当 key) - 如果只是临时判断字符属性(如大小写、数字),直接传
char给Character.isDigit(ch),别先包一层再传

















