1:瞒天过海
猜下如下代码会输出啥:
public static void main(String[] args) {
// \u000d System.out.println("coder Hydra");
}
啥也不输出,不,看结果:
神奇吧!这是因为\u000d
就是换行符的unicode编码,Java编译器会将其编译为换行符,如下编译后的结果:
这就很好理解了,如果用这种方式来埋个坑,还真是不太好发现。
这个代码:
public static void main(String[] args) {
int a=1;
// \u000d \u0061\u002b\u002b\u003b
System.out.println(a);
}
运行后是2,因为:
这个待优化代码逼格更高了:
public static void main(String[] args) throws Exception {
long startTime = System.currentTimeMillis();
//\u000d\u0054\u0068\u0072\u0065\u0061\u0064\u002e\u0073\u006c\u0065\u0065\u0070\u0028\u0032\u0030\u0030\u0030\u0029\u003b
System.out.println("waste: " + (System.currentTimeMillis() - startTime));
}
如下:
客户说慢,只有你知道为啥,你这个机灵鬼!!!
2:舍近求远
如果等于0咋的咋的,如果等于1咋的咋的逻辑咋写,这样?:
public void judge(int x){
if (x>0){
//...
}else if (x<0){
//...
}
}
NONONO,是这样:
public void judge2(int x){
if (x>>>31==0){
//...
}else if (x>>>31==1){
//...
}
}
这个逻辑还是正确的,如下:
扩展一点知识,这个代码运行结果是啥:
public static void main(String[] args) throws Exception {
int x = 345;
int what = Integer.MAX_VALUE >> 31 >> 1;
System.out.println(what);
}
看下:
0
Process finished with exit code 0
0,那这样呢:
public static void main(String[] args) throws Exception {
int x = 345;
int what = x >> 32;
System.out.println(what);
}
是不是也是0,不是的,看结果:
为啥???这是因为在执行移位运算前,Java会对操作符右边的操作数执行模32的运算,即上述代码其实是int what = x >> (32%32);
就是int what = x >> 0;
相当于啥也不做,即限制每次右移4个字节。
3:颠倒黑白
static {
try {
// 获取Boolean类中的TRUE变量,即public static final Boolean TRUE = new Boolean(true);
Field trueField = Boolean.class.getDeclaredField("TRUE");
// 暴力访问
trueField.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
// 去掉final修饰符
// 因为public static final Boolean TRUE = new Boolean(true);的定义是public static final,而这三个修饰符对应整数值如下:
/*
public static final int PUBLIC = 0x00000001; ---1
+
public static final int STATIC = 0x00000008; ---8
+
public static final int FINAL = 0x00000010; ---16
共25
trueField.getModifiers() 因此该值为25,而trueField.getModifiers() & ~Modifier.FINAL相当于是将
public static final 变为 public static,即public static Boolean TRUE = new Boolean(true);
此时modifier变为25-16=9
*/
modifiersField.setInt(trueField, trueField.getModifiers() & ~Modifier.FINAL);
// final已经去掉了,就可以反射修改其值为false了
trueField.set(null, false);
} catch(IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Boolean reality = true;
if(reality) {
System.out.println("true");
} else {
System.out.println("false");
}
}
以上代码输出啥?看结果:
false
Process finished with exit code 0
奥秘都在静态代码块了,写了详细的注释,自己看下。
4:釜底抽薪
如下直接操作内存代码:
public static void main(String[] args) throws Exception {
// 获取unsafe
Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
Unsafe unsafe =(Unsafe) unsafeField.get(null);
// 申请4字节 的内存
long addr = unsafe.allocateMemory(4);
// 设置值1
unsafe.putInt(addr,1);
// 注意这里输出的是随机值,因为分配的四字节内存,可能是任意4个字节,而该四字节因为还没有清除之前存储的数据,所以当前是什么内容是不确定的
// 你可以试下,每次运行结果都是不一样的
System.out.println(addr);
// 转int,并清理 内存之前的脏数据
int a=unsafe.getInt(addr);
System.out.println(a);
// 释放内存
unsafe.freeMemory(addr);
}
运行:
55516032
1
Process finished with exit code 0
抄的这里的文章 。