python的注释会被执行吗_老师,你确定Java注释不会被执行吗?

之前分享过一篇文章,涉及到 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 0x1

public ()V

L0

LINENUMBER 3 L0

ALOAD 0

INVOKESPECIAL java/lang/Object. ()V

RETURN

L1

LOCALVARIABLE this Lcom/cmower/dzone/secret/Test; L0 L1 0

MAXSTACK = 1

MAXLOCALS = 1

// access flags 0x9

public static main([Ljava/lang/String;)V

L0

LINENUMBER 5 L0

LDC "\\u6c89\\u9ed8\\u738b\\u4e8c"

ASTORE 1

L1

LINENUMBER 6 L1

LDC "\\u6c89\\u9ed8\\u738b\\u4e09"

ASTORE 1

L2

LINENUMBER 7 L2

GETSTATIC java/lang/System.out : Ljava/io/PrintStream;

ALOAD 1

INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V

L3

LINENUMBER 8 L3

RETURN

L4

LOCALVARIABLE args [Ljava/lang/String; L0 L4 0

LOCALVARIABLE name Ljava/lang/String; L1 L4 1

MAXSTACK = 2

MAXLOCALS = 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

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值