神奇的代码注释
该代码输出循环的次数,你觉得 count 的值是多少呢?
public class MagicTest {
public static void main(String[] args) {
int count = 0;
for (int i = 0; i < 100; i++) {
// \u000a\u007d\u007b
count++;
}
System.out.println("count = " + count);
}
}
以上代码在新版idea中会提示报错,不允许这么写了,我们在文本编辑器中写,手动编译
不要有包名,有包名在运行 class 文件时会报错
- 新建
MagicTest.java,将上面内容复制进去,进入cmd窗口
- 输入
javac MagicTest.java,会生成MagicTest.class
- 然后输入
java MagicTest,不要带 class后缀 - 可以看到输出结果:count = 1
答案是 1,不应该是100吗,我们来详细看一下
我们反编译一下刚才的 class 文件,javap -c MagicTest.class
E:\code>javap -c MagicTest.class
Compiled from "MagicTest.java"
public class MagicTest {
public MagicTest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: iconst_0
3: istore_2
4: iload_2
5: bipush 100
7: if_icmpge 16
10: iinc 2, 1
13: goto 4
16: iinc 1, 1
19: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
22: new #3 // class java/lang/StringBuilder
25: dup
26: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
29: ldc #5 // String count =
31: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
34: iload_1
35: invokevirtual #7 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
38: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
41: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
44: return
}
我也看不太懂,大概意思count只进行了一次++
我们将这个 MagicTest.class 文件拖到 idea中看一下
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
public class MagicTest {
public MagicTest() {
}
public static void main(String[] var0) {
int var1 = 0;
for(int var2 = 0; var2 < 100; ++var2) {
}
++var1;
System.out.println("count = " + var1);
}
}
可以看到,for 循环了个空,然后对 count + 1 ,接着输出了结果
原因是:Java 编译器会解析Unicode 转义序列,\u000a 是换行符,\u007d 是字符“}”,\u007b 是字符“{”
所以最上面的代码就变成了
public class MagicTest {
public static void main(String[] args) {
int count = 0;
for (int i = 0; i < 100; i++) {
//
}{
count++;
}
System.out.println("count = " + count);
}
}
新版本idea不允许这么写了,这么写很容易挨打的!!
这么写会报错吗?
public class MagicTest {
public static void main(String[] args) {
https://juejin.cn/
System.out.println("Hello world");
}
}
答案是不会
上方的 https:是java中的 goto语法的标识,带大家回忆一下java基础,进入循环后直接跳出该循环
public static void main(String[] args) {
label:
for (int j = 0; j < 10; j++) {
if (true) {
break label;
}
}
System.out.println("hello world");
}
Integer == 比较的坑
众所周知,JVM 中有个常量池,Integer 的范围是 [-128,127]
我们先看一下在范围内的情况
Integer integer1 = 1;
Integer integer2 = 1;
System.out.println(integer1 == integer2);
Integer integer3 = -128;
Integer integer4 = -128;
System.out.println(integer3 == integer4);
Integer integer5 = 127;
Integer integer6 = 127;
System.out.println(integer5 == integer6);
输出结果为:
true
true
true
在范围外的情况
Integer integer7 = -129;
Integer integer8 = -129;
System.out.println(integer7 == integer8);
Integer integer9 = 128;
Integer integer10 = 128;
System.out.println(integer9 == integer10);
输出结果为:
false
false
还有一个情况:
Integer integer11 = new Integer("1");
Integer integer12 = new Integer("1");
System.out.println(integer11 == integer12);
注意这里是 new 的对象,跟常量池就没关系了,== 比较的是对象的地址,那肯定不一样,所以输出结果为 false
总结
本文介绍了三个容易被忽略的例子,分别是Unicode 转义,goto语法,Interger == 比较的用法,如果开发过程中不加注意,可能会埋坑,所以还得加强学习呀,共勉!