本文共 1672 字,大约阅读时间需要 5 分钟。
今天review某同学的代码时发现这样一个情况:
DEBUG是一个boolean的常量,原来是if(DEBUG){ doSomething();}
后来因为要求在安全模式下不准打印log,于是改成这样:
if((!isSecMode()) && DEBUG){ doSomething();}
现在又增加了一种新的模式警用模式,于是改成这样:
if((!isSecMode()) && (!isPoliceMode()) && DEBUG){ doSomething();}
这样会造成一点性能和空间损失的。
如果编译器发现if(false)或者if(false && ...)这样的语句,直接就不会编译进字节码中,这是由短路规则所决定的。而如果把DEBUG放在最后,由于不符合短路规则,后面的语句也是没必要编译进来的,但是要保证前面的判断是要执行的。于是就生成了这样一句话if ((!ts.isSecMode()) && (!ts.isPoliceMode()));
白白要做两次判断!
下面看看完整的代码。
源代码:
public class TestSeven { public void doSomething(){ } public boolean isSecMode(){ doSomething(); return false; } public boolean isPoliceMode(){ doSomething(); return false; } private static final boolean DEBUG = false; public static void main(String[] args){ TestSeven ts = new TestSeven(); if(DEBUG && !ts.isSecMode() && !ts.isPoliceMode()){ System.out.println("DEBUG1"); } if(!ts.isSecMode() && !ts.isPoliceMode() && DEBUG){ System.out.println("DEBUG2"); } }}
反编译之后是这样的:
public class TestSeven{ private static final boolean DEBUG = false; public void doSomething() { } public boolean isSecMode() { doSomething(); return false; } public boolean isPoliceMode() { doSomething(); return false; } public static void main(String[] args) { TestSeven ts = new TestSeven(); if ((!ts.isSecMode()) && (!ts.isPoliceMode())); }}
从反编译的代码中可以看到,不管是System.out.println("DEBUG1");还是System.out.println("DEBUG2");皆是虚妄,根本就直接被编译器过滤掉了。
但是有短路规则的if(DEBUG && !ts.isSecMode() && !ts.isPoliceMode()),连一点痕迹都没留下来,而没有短路规则的第二条判断,就不得不留下if ((!ts.isSecMode()) && (!ts.isPoliceMode()));转载地址:http://hkogx.baihongyu.com/