Java:转义字符还能这样用?!

Tips: 本期食用语言:JvavJava


零、闲聊

当我在想如何更简单地将编码转换为Unicode时看到了一篇文章,直接给我 CPU 干烧了,转义字符还能这样用?!

以前写 C++ 的时候就尝试过将四位十六进制直接转换成宽字符类型(即 wchar_t 类型),但最终都没有达成目标。C++ 就是喜欢抓着 ANSI 不放,虽然办法不是没有,但都太麻烦了。绝对不是我懒


一、代码

先来看看下面这段代码:

public static void main(String[] args) {
	String a = "Hello";
	// \u000d a="world";
	System.out.println(a);
	// \u000a a="hello world!";
	System.out.println(a);
}

这段代码来自前文的一篇文章里的一篇文章,看似十分普通,会输出两遍 Hello,但现实却令人大跌眼镜:

输出:

world
hello world!

说好的 Hello 呢?

再来看看下面这段代码:

\u0009\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\u0020\u007b
\u0009\u0009
\u0009\u0009\u0053\u0074\u0072\u0069\u006e\u0067\u0020\u0061\u0020\u003d\u0020\u0022\u0048\u0065\u006c\u006c\u006f\u002c\u0020\u0077\u006f\u0072\u006c\u0064\u0021\u0022\u003b\u0020
\u0009\u0009\u0053\u0079\u0073\u0074\u0065\u006d\u002e\u006f\u0075\u0074\u002e\u0070\u0072\u0069\u006e\u0074\u006c\u006e\u0028\u0061\u0029\u003b\u0020
\u0009\u007d

是不是感觉要长脑子了?

根本不知道在写什么!
然而,把它代替原本的主函数,竟然还能运行?!

输出:

Hello, world!

二、原理

应该也有不少人看出来了,这不就是 Unicode 吗?至少也得知道这些都是两个字节的十六进制吧

事实上,雀食如此。

java 对这些 Unicode 编码先进行了一遍解码,然后再投给 jdk 进行进一步转换。具体流程本蒟蒻也不懂

可以发现,将生成的 class 文件进行反编译之后就能看懂了。

反编译之后的程序:

public static void main(String[] var0) {
   String var1 = "Hello, world!";
   System.out.println(var1);
}

而这些 Unicode 编码,事实上是通过转义字符 \u 来表示的。

而 Java 的 \u 转义字符可以写在非字符/字符串的地方,可以粗略理解为 Java 自带的宏定义。

例如:\u0020 是空格,\u0061a

在最开始的代码里,\u000d\u000a 分别代表回车和换行。

注意,回车和换行是有区别的。回车是跳转到一行的开始,换行是向下移动一格(行)。在 Windows 操作系统下,Enter 键实际上是回车和换行的结合体。

Tips:回车(\r),换行(\n)

然鹅,Java 会把 \r 当成 \r\n具体本蒟蒻也不懂,稍微写得好理解点,代码变成了这样:

public static void main(String[] args) {
	String a = "Hello";
	// 
	 a="world";
	System.out.println(a);
	// 
	 a="hello world!";
	System.out.println(a);
}

看似是注释的那一段跳到了下一行,就不再是注释了。如果在项目里面这样写,下一位是不是要疯掉


三、拓展

Java常见转义字符一览表

----------我是分界线----------
Tips:在前 128 位(0~127),Unicode 和 ASCII 对应字符完全相同。

转义字符意义ASCII 码 (十六进制)
\???三位八进制数三位八进制对应字符
\0空字符 (NULL)0x00
\a响铃 (BEL)0x07
\b退格 (BS,将当前位置移到前一列)0x08
\f换页 (FF,将当前位置移到下页开头)0x0c
\n换行 (LF,,将当前位置移到写一行开头)0x0a
\r回车 (CR,将当前位置移到本行开头)0x0d
\t水平制表 (HT,相当于 TAB 键)0x09
\uUnicode 编码对应字符
\v垂直制表 (VT)0x0b
\字符 \0x5c
字符 '0x27
"字符 "0x22
?字符 ?0x3f

看中间那列的形状是不是很像一个爱心权杖

THE END

Tips:文章一个彩蛋你找到了吗?找到了千万别发评论区 找到了点个赞就行!

  • 别忘了点赞收藏关注!
  • 结束了!
  • 如文章有误可以私信或发在评论区
  • 真的结束了!!

这下不骗你,结束! \small\color{white}这下不骗你,结束! 这下不骗你,结束!

  • 25
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值