java 好码

1【强制】不要在 foreach 循环里进行元素的 remove/add 操作。

remove 元素请使用 Iterator方式,如果并发操作,需要对 Iterator 对象加锁。

正例:

List<String> list = new ArrayList<>();

list.add("1");list.add("2");

Iterator<String> iterator = list.iterator();

while (iterator.hasNext()) {

String item = iterator.next();

if (删除元素的条件) {

iterator.remove();

}

}

反例: for (String item : list) {

if ("1".equals(item)) {

list.remove(item);

}

}

2【强制】Object 的 equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals。

正例:"test".equals(object);

反例:object.equals("test");

3 【推荐】循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展

正例:

StringBuilder sb = new StringBuilder("start");

for (int i = 0; i < 100; i++) {

sb.append("hello");

}

String result = sb.toString();

这样可以避免在循环中创建过多的临时字符串对象,提高了性能和节省了内存。

如果是在多线程环境下进行字符串操作,可以考虑使用 StringBuffer,它与 StringBuilder 类似,但是线程安全的。

总之,使用 StringBuilderStringBufferappend 方法来处理循环内的字符串连接可以提高性能、降低内存消耗。

4【强制】创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。

正例:

public class TimerTaskThread extends Thread {

public TimerTaskThread() {

super.setName("TimerTaskThread");

...

}

}

5【参考】volatile 解决多线程内存不可见问题。对于一写多读,是可以解决变量同步问题, 但是如果多写,同样无法解决线程安全问题。如果是 count++操作,使用如下类实现: AtomicInteger count = new AtomicInteger(); count.addAndGet(1); 如果是 JDK8,推 荐使用 LongAdder 对象,比 AtomicLong 性能更好(减少乐观锁的重试次数)。

【推荐】表达异常的分支时,少用 if-else 方式,这种方式可以改写成:

if (condition) {

... return obj;

}

// 接着写 else 的业务逻辑代码;

说明:如果非得使用 if()...else if()...else...方式表达逻辑,【强制】避免后续代码维 护困难,请勿超过 3 层。

正例:超过 3 层的 if-else 的逻辑判断代码可以使用卫语句、策略模式、状态模式等来实现,

其中卫语句示例如下:

public void today() {

if (isBusy()) {

System.out.println(“change time.”);

return;

}

if (isFree()) {

System.out.println(“go to travel.”);

return;

}

System.out.println(“stay at home to learn Alibaba Java Coding Guidelines.”);

return;

}

6【强制】注意 Math.random() 这个方法返回是 double 类型,注意取值的范围 0≤x<1(能够 取到零值,注意除零异常),如果想获取整数类型的随机数,不要将 x 放大 10 的若干倍然后 取整,直接使用 Random 对象的 nextInt 或者 nextLong 方法。

7. 【强制】获取当前毫秒数 System.currentTimeMillis(); 而不是 new Date().getTime(); 说明:如果想获取更加精确的纳秒级时间值,使用 System.nanoTime()的方式。在 JDK8 中, 针对统计时间等场景,推荐使用 Instant 类。