一怎么等于二?可以使用关键字作为变量名吗?我们在一组极端的Java语法难题中研究这些以及更棘手的问题。
大约12年前,我开始以各种功能为Eclipse生态系统做出贡献。迄今为止,最有趣的经历之一是致力于开发人员工具的开发和处理边缘情况,从而使其他人不必费劲。尽管在此期间我辞去了Eclipse提交人的职务,但如今仍作为Gradle Build Tool的一员致力于开发生产力工具。
在Eclipse上工作时,我深深地记得在进行重构和快速修复时在Java Tooling(JDT)的各个部分上进行过工作。毫不奇怪,事实证明,处理语言密集型部分的工作与其他非平凡算法有同样的困难–从“这很容易”过渡到“为什么我凌晨3点开始阅读Java语言规范?”
使用特定于语言的工具会使您接触到该语言必须提供的各种边缘情况和精致细节。其中一些是众所周知的,通常被视为“不专业”(您好goto)。实际上根本不知道其他人。而且,在所有应得的尊重下,我非常喜欢发现语言语法的极端情况–很多次使我认为自己知道Java语言语法的同事感到困惑。考虑到我喜欢一个很好的谜题(尤其是Java Puzzles),让我们尝试一个谜题,但仅使用Java语法,而不会出现任何运行时行为。
使用Java进行网络钓鱼
让我们从关于Java源文件的众所周知的事实开始。您可以在代码的大多数地方使用Unicode。虽然我们不能在类名中使用完整的Unicode,但是您可以添加足够的Unicode来对您的同事进行恶作剧。
作为开胃菜,在您的下一个(远程)配对会话中,只需U+037E在代码中插入一个“希腊问号”(),并看着您的同事试图找出该简单的分号有什么问题。网络钓鱼电子邮件最常使用此技术,以使URL看起来像真实URL,但实际上却指向一个截然不同的域。
由于它甚至不编译,因此您的同事很容易识别和修复。让我们开始偷偷摸摸。
猜猜下面的程序打印什么?
public static void main(String[] args) {
if (1 == 2) {
// one down, one to go: \u000a\u007d\u007b
System.out.println("1 is 2");
}