Java 8+ 应使用 java.util.Base64,因其官方、稳定、线程安全;sun.misc.BASE64Encoder 是内部API,JDK 9+ 默认禁用,会导致 IllegalAccessError。

Java 8+ 直接用 java.util.Base64,别碰 sun.misc.BASE64Encoder
Java 8 引入的 java.util.Base64 是官方、稳定、线程安全的实现;sun.misc.BASE64Encoder 属于内部 API,JDK 9+ 默认禁止反射调用,运行时会抛 IllegalAccessError 或编译失败。
- 编码用
Base64.getEncoder().encodeToString(byte[]),返回String;解码用Base64.getDecoder().decode(String),返回byte[] - 如果处理二进制数据(比如图片字节流),必须先转
byte[],不能对原始字符串直接 encode——否则默认用平台编码(如 Windows-GBK)转字节,跨平台会乱码 - 不需要额外依赖,JDK 自带,但注意最低 JDK 版本:JDK 8u121+ 修复过某些边界缓冲区问题,老版本慎用于超长输入
编码结果换行?用 Base64.getMimeEncoder() 还是 getEncoder()
标准 Base64 编码不换行;MIME 规范要求每 76 字符加 \r\n。如果你对接邮件协议或旧系统,得选对编码器。
-
Base64.getEncoder():无换行,输出紧凑,适合 URL、JSON、HTTP Header 场景 -
Base64.getMimeEncoder():每 76 字符插入\r\n,结尾带换行,符合 RFC 2045;但解码时Base64.getDecoder()能自动忽略所有空白字符,所以解码端无需匹配编码器类型 - 自定义换行间隔?不行——
Base64.Encoder没有公开构造函数,无法传入行宽参数;真有特殊需求,得自己切片 + 拼接\n
URL 安全 Base64 怎么做?别手写替换,用 Base64.getUrlEncoder()
标准 Base64 的 + 和 / 在 URL 里有特殊含义,= 作填充也容易被截断;getUrlEncoder() 专为 URI/cookie/文件名设计,用 - 替 +、_ 替 /,且默认不填充(可选)。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 生成 token 或签名参数时,优先用
Base64.getUrlEncoder().withoutPadding().encodeToString(bytes) - 解码必须用
Base64.getUrlDecoder(),不能混用getDecoder()——虽然多数情况下能碰巧成功,但遇到末尾缺失填充位时会抛IllegalArgumentException: Illegal base64 character - 注意:URL 编码器不处理 UTF-8 字符串本身,仍需先
"你好".getBytes(StandardCharsets.UTF_8),再 encode
性能和大文件:别把整个文件 load 到内存再 encode
Base64.encodeToString(byte[]) 必须持有完整字节数组,100MB 文件就占 100MB 堆内存,还额外分配约 133MB 编码后字符串(Base64 膨胀率 ~4/3),极易 OOM。
立即学习“Java免费学习笔记(深入)”;
- 大文件或流式场景,用
Base64.Encoder.wrap(OutputStream)包装目标流,边读边写:encoder.encode(new FileInputStream("in.bin")).transferTo(new FileOutputStream("out.b64")) - 别用
String.getBytes()无参重载——它依赖系统默认编码,Windows 和 Linux 表现不同;显式传StandardCharsets.UTF_8 - Android 开发注意:API 26+ 才完整支持
java.util.Base64,低版本需回退到android.util.Base64,两者 API 几乎一致,但类名和包名不同
真正麻烦的是混合场景:比如 HTTP 请求体要 Base64 编码上传,但服务端又要求 MIME 换行格式,这时候得确认对方是否真的校验换行——很多所谓“MIME 兼容”接口其实只认无换行 Base64,连 \r\n 都会解析失败。

















