为什么Java注释里的代码被执行了?

简介: 为什么Java注释里的代码被执行了?

一、背景


某天,在我的代码里写了如下这么一行注释,让我吃惊是注释里面的代码被执行了。

image.png

按常规思路,这行代码被注释了,控制台应该不会有执行结果,但是却出现了如下返回结果。

image.png

到这里,我们能大概猜测是 Unicode 解码发生在任何词汇解码之前。而 \u000d 是一个换行符,因此对注释进行了终止导致换行符后面的注释代码被执行了。


二、什么是 Unicode 逃逸?


我去 oracle 官网查看了一下 Java 语言规范(JLS 3)相关的解释,大意如下:Unicode 转义用于表示仅包含 ASCII 字符的 Unicode 符号。当您需要插入无法在源文件的字符集中表示的字符时,它将派上用场。JLS 3.3节的相关说明,Unicode 转义包含一个反斜杠字符(\),后跟一个或多个'u'字符和四个十六进制数字。

image.png

因此,例子中的 \u000d将被视为换行符。


下图为官方 JLS 文档。

image.png

这种机制的好处在于它可以在 ASCII 和任何其他编码之间来回切换,并且不需要你弄清楚注释的开始和结束位置!


三、分析求证


为了证实是不是我们分析的那样,我用了 Java 自带的工具 native2ascii 来将具有任何支持的字符编码的文件转换为具有 ASCII 或 Unicode 转义的文件。

image.png

执行如下命令便一目了然了。

image.png

image.png

我可以发现转换后的代码被换行了!


其实,我也可以通过查看 class 字节码来发现其中的端倪。

image.png

看来跟我们之前分析的一样。


四、总结


这个骚操作也保证了 Java 核心思想 —— 平台一致性。


虽然这个方式处理机制看似优雅,但是,它却带来了副作用(干扰语义),尤其是在评论中,我们一定要注意!


好了,留个思考题给各位同学,新建一个 Hi.java 文件,将下面的 Unicode 码拷贝到文件,看看执行结果会是什么呢?


\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0063\u006c\u0061\u0073\u0073\u0020\u0048\u0069\u007b\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0073\u0074\u0061\u0074\u0069\u0063\u0020\u0076\u006f\u0069\u0064\u0020\u006d\u0061\u0069\u006e\u0028\u0053\u0074\u0072\u0069\u006e\u0067\u005b\u005d\u0020\u0061\u0072\u0067\u0073\u0029\u007b\u0053\u0079\u0073\u0074\u0065\u006d\u002e\u006f\u0075\u0074\u002e\u0070\u0072\u0069\u006e\u0074\u006c\u006e\u0028\u0020\u0022\u0048\u0065\u006c\u006c\u006f\u0020\u0077\u006f\u0072\u006c\u0064\u0022\u0029\u003b\u007d\u007d


五、参考


https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.3


相关文章
|
2月前
|
Java 开发工具
【Azure Storage Account】Java Code访问Storage Account File Share的上传和下载代码示例
本文介绍如何使用Java通过azure-storage-file-share SDK实现Azure文件共享的上传下载。包含依赖引入、客户端创建及完整示例代码,助你快速集成Azure File Share功能。
371 5
|
2月前
|
Java 数据处理 API
为什么你的Java代码应该多用Stream?从循环到声明式的思维转变
为什么你的Java代码应该多用Stream?从循环到声明式的思维转变
262 115
|
2月前
|
安全 Java 编译器
为什么你的Java代码需要泛型?类型安全的艺术
为什么你的Java代码需要泛型?类型安全的艺术
187 98
|
2月前
|
Java 编译器 API
java最新版和java8的区别,用代码展示
java最新版和java8的区别,用代码展示
282 43
|
2月前
|
安全 Java 容器
告别空指针噩梦:Optional让Java代码更优雅
告别空指针噩梦:Optional让Java代码更优雅
388 94
|
2月前
|
安全 Java 容器
告别繁琐判空:Optional让你的Java代码更优雅
告别繁琐判空:Optional让你的Java代码更优雅
|
3月前
|
IDE Java 关系型数据库
Java 初学者学习路线(含代码示例)
本教程为Java初学者设计,涵盖基础语法、面向对象、集合、异常处理、文件操作、多线程、JDBC、Servlet及MyBatis等内容,每阶段配核心代码示例,强调动手实践,助你循序渐进掌握Java编程。
464 3
|
3月前
|
安全 Java 应用服务中间件
Spring Boot + Java 21:内存减少 60%,启动速度提高 30% — 零代码
通过调整三个JVM和Spring Boot配置开关,无需重写代码即可显著优化Java应用性能:内存减少60%,启动速度提升30%。适用于所有在JVM上运行API的生产团队,低成本实现高效能。
346 3
|
3月前
|
Java
java入门代码示例
本文介绍Java入门基础,包含Hello World、变量类型、条件判断、循环及方法定义等核心语法示例,帮助初学者快速掌握Java编程基本结构与逻辑。
417 0