被滥用的instanceof
instanceof滥用, 或者直接强转, 大都数情况可以用方法override, 而且应当避免使用isA(), isB()之类的写法;
比如sonA和sonB都继承自parent, 其中sonA和sonB想对parent里方法move()各自拥有独立的实现;
1 // 错误写法1 2 void test(parent p) { 3 if (p instanceof sonA) { 4 ((sonA) p).moveA(); 5 } else if (p instanceof sonB) { 6 ((sonB) p).moveB(); 7 } 8 } 9 // 错误写法2 10 void test2(parent p) { 11 if (p.isA()) { 12 ((sonA) p).moveA(); 13 } else if (p.isB()) { 14 ((sonB) p).moveB(); 15 } 16 } 17 18 // 正确写法 19 void test3(parent p) { 20 // sonA sonB里做不同的实现. 21 p.move(); 22 }
那么正确写法是在sonA和sonB中都重新实现move()来实现差异, 而不是在parent.move()里用instanceof sonA.
最终代码中不应该出现if else, 而是只有一个parent.move()方法.
性能
尽量不要在方法上加synchronized, 会阻塞每一个调用方法的对象.
应该在方法块里, 并且要缩小控制粒度.
1 // 错误写法一 2 public synchronized Form getFormFromCache(String bookPath) {
1 // 错误写法二, 粒度太大, 应该把get提取出来做双重检查 2 public Form getFormFromCache(String bookPath) { 3 FormEntry entry; 4 synchronized (formCache) { 5 entry = formCache.get(bookPath); 6 if (entry == null) { 7 entry = new FormEntry(bookPath); 8 formCache.put(bookPath, entry); 9 } 10 } 11 }
1 // 正确写法, 虽然有点繁琐, 但是性能好 2 public Form getFormFromCache(String bookPath) { 3 FormEntry entry = formCache.get(bookPath); 4 if (entry == null) { 5 synchronized (formCache) { 6 entry = formCache.get(bookPath); 7 if (entry == null) { 8 entry = new FormEntry(bookPath); 9 formCache.put(bookPath, entry); 10 } 11 } 12 } 13 }
变量与状态
对于不同状态不同实现的时候, 可以使用enum来替代int, 在enum内部做不同实现, 而不是一堆switch (state) .
public方法尽量不要用boolean入参, 尤其多个参数的时候, 会让调用者很困惑.
1 // 错误一 2 public void doSth(boolean isXX){ 3 if (isXX) { 4 //... 5 } 6 7 //... 8 } 9 10 // 正确: 拆分方法, 公共部分可以抽成private 11 public void doSth(){ 12 //... 13 } 14 15 public void doXX() { 16 //.. 17 } 18 19 // 错误二 20 public void doSth2(boolean isHorizon){ 21 22 } 23 24 // 正确使用int或者enum来标记参数, 而不是isHorizon 25 public void doSth3(int align){ 26 27 }
精简代码逻辑
多余的if else
1 if(condition) { 2 return true; 3 } 4 return false; 5 6 //改成直接return condition就行了.
繁琐的逻辑
1 if (0 <= b && b <= 1) { 2 return b; 3 } else { 4 return b < 0 ? 0 : 1; 5 } 6 //改成Math.min(Math.max(0, b), 1);
不要return null
尽量用一个空对象来描述, 而不是null. 避免外部调用的时候发生NPE.
1 // 错误写法 2 public TestNull doWrong() { 3 if (true) { 4 return null; 5 } 6 7 return new TestNull(); 8 } 9 10 //正确写法 11 public TestNull doRight() { 12 if (true) { 13 return TestNull.EMPTY; 14 } 15 16 return new TestNull(); 17 } 18 19 static class TestNull { 20 21 private static TestNull EMPTY = new TestNull(); 22 23 }