1、用偶判断,不用奇判断。因为负数会出错。

// 不使用
String str = i + "->" + (i%2 == 1? "奇数": "偶数");
// 而使用
String str = i + "->" + (i%2 == 0? "偶数": "奇数");

2、使用整数类型处理货币

(1)使用BigDecimal,与数据库Decimal类型字段映射时。

(2)货币扩大100倍,使用整形。

3、不要让类型默默转换。使用主动声明式转换。

java是先运算,后自动转换类型的。

long dis = 1L * 60 * 8

4、数字越界使验证条件失效。

边界测试:0,正最大,负最小。

5、四舍五入问题。Math.round和银行家算法。

Math.round(10.5) 结果 10;

Math.round(-10.5) 结果 -10;

BigDecimal i = d.multipy(r).setScale(2, RoudingMode.HALF_EVEN); // 银行家算法

6、包装类型参与运算要做null值检验。否则会报错。

for (Integer i : list) {
count += (i != null) ? i : 0;
}

7、优先使用整形池。

Integer i = Integer.valueOf(27);

节省空间,提高性能。判断相等要用equals方法。

8、优先使用基本类型。

9、不要覆写静态方法。

public class Client {
public static void main(String[] args) {
Base base = new Sub();
base.doStatic(); // 覆写后,会调用父类静态方法
base.doSomething(); // 覆写后,会调用子类非静态方法
}

  在子类中构建与父类相同的方法名、输入输出参数、访问权限(可扩大),且父类、子类都是静态方法的行为叫做隐藏。目的是隐藏父类静态方法,实现子类静态方法。

  @Override注解可以用于覆写,不能用于隐藏。

10、构造函数尽量简化。不抛异常、不做复杂运算。

做简单的构造函数,并将复杂问题移到start方法中,等待调用。

11、不要在构造函数中声明初始化其他类。

12、使用构造函数精炼代码

public class Client {
{
System.out.println("执行构造代码块");
}
public Client() {
System.out.println("执行无参构造");
}
public Client(String str) {
System.out.println("执行有参构造");
}
} // 以上代码等价于: public class Client {
public Client() {
System.out.println("执行构造代码块");
System.out.println("执行无参构造");
}
public Client(String str) {
System.out.println("执行构造代码块");
System.out.println("执行有参构造");
}
}

  编译器会将代码块插入到每个构造函数中,在super()之后;并且构造函数中调用this()时不会再次插入。

13、内部类模拟实现多重继承。

class Son extends FatherImpl implements Mother {
@Override
public int strong() {
return super.strong() + 1;
}
@Override
public kind() {
return new MotherSpecial().kind();
}
private class MotherSpecial extends MotherImpl {
public int kind() {
return super.kind() - 1;
}
}
} class Daughter extends MotherImpl implements Father {
@Override
public int strong() {
return new FatherImpl() {
@Override
public int strong() {
return super.strong() - 2;
}
}.strong();
}
}

14、让工具类不可实例化

public final Class Math {
private Math() {}
}
//以上不允许实例化,但利用反射修改构造函数的权限还是可能的。更彻底的方法是:
public class UtilsClass {
private UtilsClass() {
throw new Error("不要实例化我");
}
}

15、避免对象的浅拷贝

  拷贝在内存中进行,性能方面比直接new对象快很多,特别是在大对象生成上,提升性能非常显著。

16、推荐使用序列化实现对象的拷贝

17、覆写equals时考虑自反性、对称性(考虑null)、传递性。

18、在equals中使用getClass进行类型判断,而不使用instanceof。

19、覆写equals方法必须覆写hashCode方法。

20、推荐覆写toString方法,因为默认方法不友好,打印不出有用信息。

21、特殊类:package-info类。

22、不要主动调用垃圾回收。这会停止所有响应,让出资源检查每个对象。

23、推荐String直接赋值,而不是new String("")赋值。(原因:字符串池)

24、String, replace和replaceAll的区别:replaceAll传递的第一个参数是正则表达式。

25、字符串拼接:append最快(数组拷贝),concat次之(数组拷贝后,创建String对象),加号最慢(每次新建StringBuilder,append后,toString转为字符串)。

26、推荐在复杂字符串操作中使用正则表达式。

27、Arrays.asList陷阱。

  泛型类型只支持包装类型,不支持基本类型。

// 避免使用:
int data[] = {1,2,3}
List list = Arrays.asList(data);
// list.size() : 1
//应该使用:
Integer data[] = {1,2,3};
List list = Arrays.asList(data);
// list.size : 3

  asList产生的list不可修改。

28、不同列表的不同遍历方法。

  ArrayList实现了RandomAccess接口,使用下标访问更高效。LinkedList使用迭代访问效率更高。

public static int average(List<Integer> list) {
int sum = 0;
if (list instanceof RandomAccess) {
for (int i = 0, size = list.size(); i < size; i++) {
sum += list.get(i);
}
} else {
for (int i : list) {
sum += i;
}
}
return sum / list.size();
}

29、频繁插入删除使用LinkedList。

30、列表相等只关心元素数据。

  ArrayList和Vector只有元素相等,则equals为true。其他集合类型相似。

31、subList是原List的视图,subList的修改会反映到原List上。生成子列表后不要再操作原列表,子列表会报错。

32、compareTo与equals要同步。

33、Collections.shuffle(lists)打乱顺序。

34、非稳定性排序用List。

SortedSet接口只定义了集合加入元素时的排序,不保证修改元素后的排序结果,因此TreeSet适应于不变量的集合排序。建议使用List和Collection.sort()解决。

35、switch枚举值可能会出现空指针异常。

原因是switch通过枚举值的排序值判断。如Season.Spring.ordinal()。

36、枚举类型switch的default代码中加AssertionError报错,方便排查新增枚举值而逻辑没有同步改动的错误。

37、枚举使用valueOf要校验,加try-catch。

38、枚举实现工厂方法模式更简洁、高效、不易出错。

enum CarFactory {
FordCar {
public Car create() {
return new FordCar();
}
},
BuickCar {
public Car create() {
return new BuickCar();
}
};
public abstract Car create();
} public static void main(String[] args) {
Car car = CarFactory.BuickCar.create();
}

39、枚举类型使用EnumSet和EnumMap提高效率。

40、不要在finally块中处理返回值。

无论是在finally块中加入return语句,还是在修改return的值或引用值、再返回,都不可以。会覆盖try块中的return值,屏蔽异常,造成假象,增加代码复杂性。

41、不要在构造函数中抛出异常。

42、使用Throwable获得栈信息。

43、多线程继承Thread不要覆写start方法。

44、启动线程前的stop方法不可靠。

start之前调用stop方法会将线程置为不可启用状态,但start方法本身的缺陷导致会先启动后停止,因此应该自己判断线程是否启用。

45、不使用stop方法停止线程。

stop方法是一个过时的方法。无法保证完整性,会破坏原子逻辑。

此外,interrupt方法不能终止正在执行的线程,只改变终端标识。

应该自己编码实现,比如修改终止判断条件。或者使用线程池ThreadPoolExecutor的shutdown方法。

46、线程优先级只使用三个。

Java线程支持10个优先级(另外有一个不可设的只供jvm使用的优先级)。

但不同机器对优先级的支持不同,所以只推荐使用MIN_PRIORITY, NORM_PRIORITY, MAX_PRIORITY三个优先级,但也不一定完全保证顺序。

47、volatile不能保证数据同步,只能保证线程获取到最新值。

48、异步运算考虑使用Callable接口。

Runnable接口和继承Thread类的run方法都没有返回值,不能跑出异常。Executor可以解决该问题。

49、克隆对象不比直接生成对象效率高。

因为java对new对象进行了优化,所以不要轻易使用clone。

改善java程序的更多相关文章

  1. 博友的 编写高质量代码 改善java程序的151个建议

    编写高质量代码 改善java程序的151个建议 http://www.cnblogs.com/selene/category/876189.html

  2. 编写高质量代码改善java程序的151个建议——导航开篇

    2014-05-16 09:08 by Jeff Li 前言 系列文章:[传送门] 下个星期度过这几天的奋战,会抓紧java的进阶学习.听过一句话,大哥说过,你一个月前的代码去看下,慘不忍睹是吧.确实 ...

  3. 编写高质量代码:改善Java程序的151个建议(第二章:基本类型)

    编写高质量代码:改善Java程序的151个建议(第二章:基本类型) 目录 建议21:用偶判断,不用奇判断 建议22:用整数类型处理货币 建议23:不要让类型默默转换 建议24:边界还是边界 建议25: ...

  4. 编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则)

    编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则) 目录 建议1: 不要在常量和变量中出现易混淆的字母 建议2: 莫让常量蜕变成变量 建议3: 三元操作符的类型务 ...

  5. 编写高质量代码改善java程序的151个建议——[1-3]基础?亦是基础

    原创地址:   http://www.cnblogs.com/Alandre/  (泥沙砖瓦浆木匠),需要转载的,保留下! Thanks The reasonable man adapts himse ...

  6. 编写高质量代码:改善Java程序的151个建议 --[117~128]

    编写高质量代码:改善Java程序的151个建议 --[117~128] Thread 不推荐覆写start方法 先看下Thread源码: public synchronized void start( ...

  7. 编写高质量代码:改善Java程序的151个建议 --[106~117]

    编写高质量代码:改善Java程序的151个建议 --[106~117] 动态代理可以使代理模式更加灵活 interface Subject { // 定义一个方法 public void reques ...

  8. 编写高质量代码:改善Java程序的151个建议 --[78~92]

    编写高质量代码:改善Java程序的151个建议 --[78~92] HashMap中的hashCode应避免冲突 多线程使用Vector或HashTable Vector是ArrayList的多线程版 ...

  9. 编写高质量代码:改善Java程序的151个建议 --[65~78]

    编写高质量代码:改善Java程序的151个建议 --[65~78] 原始类型数组不能作为asList的输入参数,否则会引起程序逻辑混乱. public class Client65 { public ...

  10. 编写高质量代码:改善Java程序的151个建议 --[52~64]

    编写高质量代码:改善Java程序的151个建议 --[52~64] 推荐使用String直接量赋值 Java为了避免在一个系统中大量产生String对象(为什么会大量产生,因为String字符串是程序 ...

随机推荐

  1. JVM学习思考

    毕业以来技术上一直没有太大进步,仔细一想可能是没有做技术分享,我喜欢把学习总结记录在印象笔记中,那么理解的是对是错也就没人能评判一下.为了技术进步,接下来将陆续把一些学习总结迁移到博客园中,欢迎大家多 ...

  2. 学习RabbitMQ(四)

      I. 消息中间件特点: 1,异步处理模式 消息发送者可以发送一个消息而无需等待响应,消息发送者将消息发送到一条虚拟的通道或队列上,消息接收者则订阅或监听该通道,一条消息可能最终转发给一个或多个消息 ...

  3. Java中final的使用

    原文链接https://www.cnblogs.com/dolphin0520/p/10651845.html 作者Matrix海 子 本文为笔记 0. 概述 final和static一样都是修饰词, ...

  4. 8.5_线性控制器设计_轨迹跟踪(Follow a Desired Path)

    平衡点时所有的导数都为0 simulink中建立状态方程模型

  5. react、react-router、redux 也许是最佳小实践1

    小前言 这是一个小小的有关react的小例子,希望通过一个小例子,可以让新手更好的了解到react.react-router4.0.redux的集中使用方法. 这是基于create-react-app ...

  6. WordPress 网站开发“微信小程序“实战(二)

    原文链接:https://devework.com/wordpres...,转载请用明链注明来源,谢谢! 本文是"WordPress 开发微信小程序"系列的第二篇,本文记录的是开发 ...

  7. potoshop cs6安装配置16错误解决办法(win10系统)

    问题截图如下: 解决方法: 右击图标选择属性:选择兼容性-->兼容模式-->以管理员身份运行-->应用 然后就可以打开了!

  8. audio小记

    写H5活动页的需要音频,图标旋转停止保持当时的旋转角度,这样视觉体验效果好: 之前写法是点击pause()就直接停止动画,后来发现了animation有个比较好的属性animation-play-st ...

  9. Linux下编写和加载 .ko 文件(编写linux驱动)

    一..ko 文件介绍 .ko文件是kernel object文件(内核模块),该文件的意义就是把内核的一些功能移动到内核外边, 需要的时候插入内核,不需要时卸载. 二.优点 (1)这样可以缩小内核体积 ...

  10. zabbix proxy cannot perform check now for itemid [xxxxx]: item is not in cache

    情况 接上次做完容器部署proxy后,为其添加host进行添加任务. 发现一直没有数据,就到item里面执行 execute now. 然后过了几分钟回来一看,还是没有. Emmm,看下log吧. S ...