Java 源码中的 Unicode 逃逸问题,别被注释给骗了

背景

看了一段项目源码,定义了一个 List 对象,但是往该列表对象 add 的代码前面有注释符号,但是程序运行时列表中却存在对象,为什么呢?仔细看了一下,注释符号和 add 代码之间有一个特殊符号 \u000d,这到底是什么东西呢?

奇怪的代码

bash 复制代码
public List<String> getData() {
	List<String> data = new ArrayList<>();
	
	for (int i = 0; i < 10; i++) {
		// 注意,这里有个障眼法是 unicode 的换行符
		// \u000d data.add(i);
	}

	logger.info("data count is {}", data.size());
	return data;
}

运行结果:

基本原理

众所周不知「恕我孤陋寡闻,我没看过这种用法」,Java 编译器编译代码时会解析 unicode 字符,而代码中存在特殊字符的 unicode 符号时,就会产生障眼。

几个主要特殊符号:

  1. \u000a 换行
  2. \u000d 回车
  3. \u007d 左花括号 {
  4. \u007b 右花括号 }

启示录

想起刚入行的时候,看过一本电子书《疯狂的 Java 讲义》,书中介绍了很多 Java 的奇怪玩法,现在大部分都忘记了。

但对单例代码的漏洞,一直记忆犹新。即通过反序列化后创建的类可以打破单例,解决办法是重新序列化方法的 writeObject 保证也是单例。具体细节已经遗忘了,回忆了一下《序列化对单例模式的破坏》

至于 Unicode 字符逃逸,项目中出现这类迷惑代码,普通开发怎么看得懂呢?尤其是我这种头脑比较简单的人,只会写简单代码,一见到复杂绕绕的代码就懵了哇!

话说回来,unicode 在某种场合还是有用的,比如绕过平台的敏感词检测,之前发布某篇文章通不过的时候,转换成 unicode 编码就过去了。作为程序员交流的暗语也是不错的!

bash 复制代码
\u8001\u733f\u4e0b\u73ed\u4e86
相关推荐
橙淮2 小时前
并发编程(六)
java·jvm
拽着尾巴的鱼儿2 小时前
springboot openfeign 自定义feign 接口重试机制
java·spring boot·后端
白露与泡影2 小时前
2026大厂Java面试题大全!牛客网最新版
java·开发语言
EntyIU3 小时前
JVM内存与GC笔记
java·jvm·笔记
XS0301063 小时前
并发编程 六
java·后端
yaoxin5211233 小时前
419. 现代 Java IO 最佳实践 - 写入文本文件
java·windows·python
雪宫街道3 小时前
synchronized 锁的范围:对象锁、类锁与代码块锁
java·jvm·后端·面试
x***r1514 小时前
linux安装 jdk-8u291-linux-x64.tar.gz 详细步骤(解压配置环境变量)
java
极光代码工作室4 小时前
基于SpringBoot的校园论坛系统
java·springboot·web开发·后端开发
XS0301064 小时前
Spring Bean 作用域 & 生命周期
java·后端·spring