来源 | 沉默王二

责编 | Carol

头图 | CSDN 下载自 视觉中国

之前在 CSDN 上分享过一篇文章,涉及到 Java 中的注释,就信誓旦旦地写了一句话:“注释是不会被执行的!”结果,有小伙伴留言说,“老师,你确定吗?”

我这个人一直有个优点,就是能听得进去别人的声音,管你是赞美的还是批评的,从来都是虚心接受。因为我相信,大多数小伙伴都是出于善的目的。

况且,我在技术上从来没想过要成为多牛逼的大佬,就是喜欢分享的感觉,而已。很多文章中出现的错误,我都原封不动的保留,因为如果把修正了,那么留言中那些指出错误的人,在后来的读者眼里,就会觉得不合时宜。

那些 diss 我的小伙伴们,放心,我是不会介意的。

尽管如此,但对于注释这件事,真的是不能忍啊!注释肯定不会被执行啊,我想这位小伙伴一定是在讽刺我。于是我就私信问他为什么,然后他就甩给了我下面这段代码:

public class Test {public static void main(String[] args) {String name = "沉默王二";// \u000dname="沉默王三";System.out.println(name);}
}

我拷贝到 IDEA 中跑了一下,结果程序输出的结果出乎我的意料:

沉默王三

竟然是王三,不是王二。看到这个结果,我算是彻底懵逼了。

那一刹那,我感觉这十来年的 Java 算是白学了。大学那会,老师说注释是不会执行的;就连《编程思想》里也说注释是不会执行的。那现在谁能告诉我这到底为什么?

不是说程序的世界很单纯吗?不是 0 就是 1?事情搞到这个地步,只能花心思好好研究一下了。

单纯从代码上来看,问题应该出在那串特殊的字符上——\u000d,如果不是它在作怪,把 name 的值由“沉默王二”修改为了“沉默王三”,就没有别的原因了——没别的,凭借多年的工作经验,找问题的根源我还是很得心应手的。

\u000d 虽然看上去比较陌生,但我知道它是一个 Unicode 字符。问了一下搜索引擎后,知道它代表一个换行符——一种恍然大悟的感觉啊。我知道,Java 编译器不仅会编译代码,还会解析 Unicode 字符。

我大致看了一眼上面这段代码编译后的字节码,它长下面这个样子:

// class version 58.65535 (-65478)
// access flags 0x21
public class com/cmower/dzone/secret/Test {// compiled from: Test.java// access flags 0x1public <init>()VL0LINENUMBER 3 L0ALOAD 0INVOKESPECIAL java/lang/Object.<init> ()VRETURNL1LOCALVARIABLE this Lcom/cmower/dzone/secret/Test; L0 L1 0MAXSTACK = 1MAXLOCALS = 1// access flags 0x9public static main([Ljava/lang/String;)VL0LINENUMBER 5 L0LDC "\u6c89\u9ed8\u738b\u4e8c"ASTORE 1L1LINENUMBER 6 L1LDC "\u6c89\u9ed8\u738b\u4e09"ASTORE 1L2LINENUMBER 7 L2GETSTATIC java/lang/System.out : Ljava/io/PrintStream;ALOAD 1INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)VL3LINENUMBER 8 L3RETURNL4LOCALVARIABLE args [Ljava/lang/String; L0 L4 0LOCALVARIABLE name Ljava/lang/String; L1 L4 1MAXSTACK = 2MAXLOCALS = 2
}

嗯,表示看不懂。不过没关系,把它反编译一下就行了,于是我看到下面这段代码:

public class Test {public Test() {}public static void main(String[] args) {String name = "沉默王二";name = "沉默王三";System.out.println(name);}
}

咦,两个反斜杠  // 真的不见了,这可以确定一点——注释确实是不会执行的。只不过 \u000d 把 name="沉默王三"; 挤到了 // 注释的下一行,就好像下面这段代码的样子:

public class Test {public static void main(String[] args) {String name = "沉默王二";//name="沉默王三";System.out.println(name);}
}

那这算不算是 Java 的 bug 呢?说算也不算。

因为通过允许 Java 源代码包含 Unicode 字符,可以确保在世界上任何一个区域编写的代码在其他地方执行。

老实说,这段话是我从网上找到,好像明白点啥,又好像不明白。那再来看一段代码:

double π = Math.PI;
System.out.println(\u03C0);

假如说程序员小王在创建周期率这个变量的时候,不知道 π 这个字符怎么敲出来,那么他就可以选择使用 \u03C0 来替代——编译器知道 \u03C0 就是 π 这个变量(编译器会在编译其他代码之前先解析 Unicode 字符)。

只能说 \u000d 是一种例外吧。

当然了,除非特殊情况,不要在源代码中包含 Unicode 字符,以免更改源代码的本意。

这篇文章没有别的意思,我也不想探究过于深奥的东西,纯粹是提高一下小伙伴们的认知:注释有可能被编译器执行。就好像,鲁迅如果不知道茴香豆的“茴”字有 4 种写法,那他就没办法让孔乙己在鲁镇的那家茶馆里装逼。

当然了,如果有小伙伴想体验一下装逼的感觉的话,可以把下面这段代码保存在一个名叫 Ugly.java 的文件中:

\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0020\u0020\u0020\u0063\u006c\u0061\u0073\u0073\u0020\u0055\u0067\u006c\u0079\u007b\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0073\u0074\u0061\u0074\u0069\u0063\u0076\u006f\u0069\u0064\u0020\u006d\u0061\u0069\u006e\u0028\u0053\u0074\u0072\u0069\u006e\u0067\u005b\u005d\u0020\u0020\u0020\u0020\u0020\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\u0022\u002b\u0022\u006f\u0072\u006c\u0064\u0022\u0029\u003b\u007d\u007d

在命令行中先执行 javac Ugly.java,再执行 java Ugly 命令就可以看到程序结果了:

Hello world

体验过后,就拉到吧。反正写这样的代码谁也看不懂,除了机器。

更多精彩推荐
☞一文浓缩 60 年,程序员不可不知的开源秘史!
☞CSDN总部落户长沙,共建中国开发者产业中心城市!
☞雷军喜提第四家上市公司,金山云上市首日暴涨 40%
☞CycleGan人脸转为漫画脸,牛掰的知识又增加了!| 附代码
☞触发死锁怎么办?MySQL 的死锁系列:锁的类型以及加锁原理了解一下!
☞带血的战士| 吴忌寒传
你点的每个“在看”,我都认真当成了喜欢

老师,你确定注释不会被执行吗?相关推荐

  1. 老师,你确定Java注释不会被执行吗?

    之前在 CSDN 上分享过一篇文章,涉及到 Java 中的注释,就信誓旦旦地写了一句话:"注释是不会被执行的!"结果,有小伙伴留言说,"老师,你确定吗?" 我这 ...

  2. python语言中的注释会不会被执行_老师,你确定注释不会被执行吗?

    来源 | 沉默王二 责编 | Carol 头图 | CSDN 下载自 视觉中国 之前在 CSDN 上分享过一篇文章,涉及到 Java 中的注释,就信誓旦旦地写了一句话:"注释是不会被执行的! ...

  3. java注释还能运行_老师,你确定Java注释不会被执行吗?

    之前在博客上分享过一篇文章,涉及到 Java 中的注释,就信誓旦旦地写了一句话:"注释是不会被执行的!"结果,有小伙伴留言说,"老师,你确定吗?" 我这个人一直 ...

  4. 代码注释掉还能执行_日志消息是可执行代码和注释

    代码注释掉还能执行 尽管在一个人的代码中应添加多少注释之间存在意见分歧,但我认为可以肯定地说,大多数开发人员都同意以下代码段中的注释是多余的: // increment the total total ...

  5. MySQL注释形式_可执行注释语句(/*!...*/)_数据库注释_数据库脚本注释_SQL脚本注释格式_SQL脚本注释分类

    文章目录 单行注释 多行注释 可执行注释 为什么要把可执行的 SQL 语句写在注释里面呢? 注释示例 导入数据时禁止/激活索引 测试禁止索引再导入数据的效率 单行注释 SELECT * from tf ...

  6. Java注释代码也会执行之Unicode编码解码

    整理Java知识点时,在注释中一次无意的书写,导致编译失败,竟然报"非法的Unicode转义".本着IT人钻研的精神,促使自己有必要深入了解Unicode编码解码的正确用法. 1. ...

  7. HDU1434 幸福列车【模拟+优先队列】(老师程序代码注释)

    幸福列车 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others) Total Su ...

  8. 浅显易懂 Makefile 入门 (08)— 默认 shell (/bin/sh)、命令回显、make参数(-n 只显示命令但不执行,-s 禁止所有回显)、单行命令、多行命令、并发执行

    1. shell 相关 1.1 默认 shell Makefile 所使用的命令是由 shell 命令行组成,他们是一条一条执行的. 多个命令之间要使用分号隔开,Makefile 中的任何命令都要以 ...

  9. python使用符号#表示单行注释-【经济金融及Python应用讲义】Python编程规范之注释...

    原标题:[经济金融及Python应用讲义]Python编程规范之注释 来源:计量经济学服务中心 经济金融及Python应用讲义 一.注释 1.为什么需要注释 如果代码的编写者在这里添加了备注说明,那么 ...

最新文章

  1. sublime几个插件
  2. java的输出流包括_【转】输入/输出流 - 深入理解Java中的流 (Stream)
  3. 官宣弃用Java 8!Kafka 3.0.0 新功能get
  4. Linux日志系统-02:logrotate简介
  5. LeetCode-剑指 Offer 18. 删除链表的节点
  6. 成功解决TypeError: a bytes-like object is required, not 'str'
  7. 架构设计(ASP.NET MVC+Knockout+Web API+SignalR)
  8. IIS+ASP+MySQL8.0+数据库连接解决方案(2019.7)
  9. 公主病 - 百度百科
  10. Linux窗口按钮大小,Fitts: 给Ubuntu窗口一个大按钮
  11. 美国进步派民主党众议员寻求大幅扩大拜登第二项支出计划规模
  12. 漫画贴:16岁和36岁打球的区别,你是否怀念球场上那个年少的你?
  13. Mybatis数据库连接报错:对实体 “characterEncoding“ 的引用必须以 ‘;‘ 分隔符结尾
  14. 复变函数、运筹学与概率论知识总结
  15. 1分钟获取上千ID,暴力破解、端口扫描、拖库攻击如何防范
  16. Android 图像按钮ImageButton
  17. docker部署达梦流程记录(DM7和DM8)
  18. Intellij Idea 全屏设置
  19. 激活windows系列地址
  20. 【音视频】浅学ISP数据处理流程

热门文章

  1. Django之--POST方法处理表单请求
  2. ubuntu在vmware下使用问题
  3. 最全的常用正则表达式大全
  4. 二叉搜索树(HDU3791)
  5. 在Asciidoc中的多级列表以及缩进的使用
  6. 《机器学习实战》学习总结(三)朴素贝叶斯在文本分类的应用
  7. GitBook Editor不能pull新Book时的处理
  8. Pytorch 保存中途训练的模型
  9. 发生无法识别的错误_车牌识别系统的核心部件抓拍摄像机怎么安装?
  10. 【自用】docker命令记录