Java 代码质量

时间:2023-03-08 19:39:03

被滥用的instanceof


instanceof滥用, 或者直接强转, 大都数情况可以用方法override, 而且应当避免使用isA(), isB()之类的写法;

比如sonA和sonB都继承自parent, 其中sonA和sonB想对parent里方法move()各自拥有独立的实现;

 // 错误写法1
void test(parent p) {
if (p instanceof sonA) {
((sonA) p).moveA();
} else if (p instanceof sonB) {
((sonB) p).moveB();
}
}
// 错误写法2
void test2(parent p) {
if (p.isA()) {
((sonA) p).moveA();
} else if (p.isB()) {
((sonB) p).moveB();
}
} // 正确写法
void test3(parent p) {
// sonA sonB里做不同的实现.
p.move();
}

那么正确写法是在sonA和sonB中都重新实现move()来实现差异, 而不是在parent.move()里用instanceof sonA.

最终代码中不应该出现if else, 而是只有一个parent.move()方法.

性能


尽量不要在方法上加synchronized, 会阻塞每一个调用方法的对象.

应该在方法块里, 并且要缩小控制粒度.

     // 错误写法一
public synchronized Form getFormFromCache(String bookPath) {
     // 错误写法二, 粒度太大, 应该把get提取出来做双重检查
public Form getFormFromCache(String bookPath) {
FormEntry entry;
synchronized (formCache) {
entry = formCache.get(bookPath);
if (entry == null) {
entry = new FormEntry(bookPath);
formCache.put(bookPath, entry);
}
}
}
     // 正确写法, 虽然有点繁琐, 但是性能好
public Form getFormFromCache(String bookPath) {
FormEntry entry = formCache.get(bookPath);
if (entry == null) {
synchronized (formCache) {
entry = formCache.get(bookPath);
if (entry == null) {
entry = new FormEntry(bookPath);
formCache.put(bookPath, entry);
}
}
}
}

变量与状态


对于不同状态不同实现的时候, 可以使用enum来替代int, 在enum内部做不同实现, 而不是一堆switch (state) .

public方法尽量不要用boolean入参, 尤其多个参数的时候, 会让调用者很困惑.

     // 错误一
public void doSth(boolean isXX){
if (isXX) {
//...
} //...
} // 正确: 拆分方法, 公共部分可以抽成private
public void doSth(){
//...
} public void doXX() {
//..
} // 错误二
public void doSth2(boolean isHorizon){ } // 正确使用int或者enum来标记参数, 而不是isHorizon
public void doSth3(int align){ }

精简代码逻辑


多余的if else

 if(condition) {
return true;
}
return false; //改成直接return condition就行了.

繁琐的逻辑

1 if (0 <= b && b <= 1) {
  return b;
} else {
return b < 0 ? 0 : 1;
}
//改成Math.min(Math.max(0, b), 1);

不要return null


尽量用一个空对象来描述, 而不是null. 避免外部调用的时候发生NPE.

     // 错误写法
public TestNull doWrong() {
if (true) {
return null;
} return new TestNull();
} //正确写法
public TestNull doRight() {
if (true) {
return TestNull.EMPTY;
} return new TestNull();
} static class TestNull { private static TestNull EMPTY = new TestNull(); }