最怕同事写出这样的代码。。。
嗨,我是虎哥,一个在代码堆里摸爬滚打多年的老码农。今天咱们聊聊那些让人血压飙升的代码小技巧。
作为一名老码农,我见过各种各样的代码,但有些代码真是让我忍不住想拍桌子。
今天就给大家总结一些Java中的代码小技巧,掌握这些技巧后,你也能写出让同事抓狂的代码。
瞒天过海
有些程序员喜欢在代码注释里“下毒”,来看一段代码:
public static void main(String[] args) {// \u000d System.out.println("coder Duck");}
是不是很意外?注释中的代码居然被执行了!这是因为 \u000d 是 Unicode 转义字符,表示换行符。
Java 编译器会解析 Unicode 编码并将其替换为对应的字符。所以,解析后代码变成了:
public static void main(String[] args) {//System.out.println("coder Duck");}
public static void main(String[] args) {int a = 1;// \u000d \u0061\u002b\u002b\u003bSystem.out.println(a);}这段代码执行后会打印 2,因为注释中的 \u0061\u002b\u002b\u003b 实际上是 a++; 的 Unicode 编码转义。这种写法可以用来掩人耳目,让人一眼看不出代码的真实意图。
舍近求远:复杂化简单的逻辑。
让简单的事情复杂化也是一种常见的迷惑同事的方法。比如判断一个整数的正负,可以简单写成:
public void judge(int x){if (x > 0) {// ...} else if (x < 0) {// ...}}
public void judge2(int x){if (x >>> 31 == 0) {// ...} else if (x >>> 31 == 1) {// ...}}
int ZERO = Integer.MAX_VALUE >>> 31 >>> 1;
颠倒黑白
public class TrueTest {public static void main(String[] args) {Boolean reality = true;if (reality) {System.out.println("true");} else {System.out.println("false");}}}
static {try {Field trueField = Boolean.class.getDeclaredField("TRUE");trueField.setAccessible(true);Field modifiersField = Field.class.getDeclaredField("modifiers");modifiersField.setAccessible(true);modifiersField.setInt(trueField, trueField.getModifiers() & ~Modifier.FINAL);trueField.set(null, false);} catch (IllegalAccessException | NoSuchFieldException e) {e.printStackTrace();}}
原理是通过反射修改了 Boolean 类中的 TRUE 变量,将其值设为 false,从而使得 true 变量在自动装箱时被替换为 false。
化整为零
如果要让 if 和 else 中的代码都执行,可以使用一些特殊的技巧。来看这个例子:
public static void judge(String param){if (param == null || new Duck(){{ Duck.check(null); }}.equals("Duck")) {System.out.println("step one");} else {System.out.println("step two");}}
这是因为 if 条件中使用了匿名内部类的实例化初始块,它会在条件判断时执行,从而导致 judge() 方法被调用两次,分别满足 if 和 else 条件。
釜底抽薪
Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");unsafeField.setAccessible(true);Unsafe unsafe = (Unsafe) unsafeField.get(null);
void test() {long addr = unsafe.allocateMemory(4);unsafe.putInt(addr, 1);int a = unsafe.getInt(addr);System.out.println(a);unsafe.freeMemory(addr);}
这段代码通过 allocateMemory 申请内存,通过 putInt 写入值,再通过 getInt 读取值,最终实现赋值操作。虽然功能强大,但使用不当会导致程序崩溃。再来看一个更复杂的例子:
void test2(){long addr = unsafe.allocateMemory(4);long addr2 = unsafe.reallocateMemory(addr, 4 * 2);unsafe.putInt(addr, 1);for (int i = 0; i < 2; i++) {unsafe.copyMemory(addr, addr2 + 4 * i, 4);}System.out.println(unsafe.getInt(addr));System.out.println(unsafe.getLong(addr2));unsafe.freeMemory(addr);unsafe.freeMemory(addr2);}
4294967297
这是因为新的8字节内存空间 addr2 中存储的二进制数字是 100000000000000000000000000000001,转化为十进制的 long 类型后正好对应4294967297。
鱼死网破
利用反射机制,可以在运行时动态地替换父类的方法,实现一些意想不到的效果。来看下面这个例子:
public class Parent {public void show() {System.out.println("Parent");}}public class Child extends Parent {static {try {Method method = Parent.class.getDeclaredMethod("show");method.setAccessible(true);Field field = Method.class.getDeclaredField("modifiers");field.setAccessible(true);field.setInt(method, method.getModifiers() & ~Modifier.FINAL);method.invoke(new Child(), (Object[]) null);} catch (Exception e) {e.printStackTrace();}}@Overridepublic void show() {System.out.println("Child");}public static void main(String[] args) {new Child().show();}}
Child
这里我们在 Child 类的静态代码块中使用反射机制调用了父类的 show 方法,这种操作看似高深,但实际上违背了继承和多态的基本原则,让代码难以维护。
最后
虎哥提醒大家,写代码不是炫技的舞台,而是解决问题的工具。让我们一起写出让人愉快维护的代码吧。
目前,对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
资料包含了《IDEA视频教程》、《最全python面试题库》、《最全项目实战源码及视频》及《毕业设计系统源码》,总量高达650GB。全部免费领取!全面满足各个阶段程序员的学习需求!