20191126-编写高质量代码:1-Java开发中

  1. 不要在常量和变量中出现易混淆的字母
  2. 莫让常量蜕变成变量
    常量就是常量,在编译期就必须确定其值,不应该在运行期更改
    务必让常量的值在运行期保持不变
  3. 三元操作符的类型务必一致
    三元操作符是if-else的简化写法
int i=80;
System.out.println(String.valueOf(i<100 ? 90 : 100));
System.out.println(String.valueOf(i<100 ? 90 : 100.0));

运行结果:
在这里插入图片描述
三元操作符类型转换规则:

  • 若两个操作数不可转换,则不做转换,返回值为Object类型
  • 若两个操作数是明确类型的表达式(比如变量),则按照正常的二进制数字来转换,int转换为long,long转换为float等
  • 如两个操作数中有一个数字S,另外一个是表达式,且其类型标示为T,那么若数字S在T的范围内,则转换为T的类型;否则T转为S类型。返回值类型为范围较大者。
  1. 避免带有变长参数的方法重载
  2. 别让null值和空值威胁到变长方法
  3. 覆写变长方法也循规蹈矩(覆写的方法参数与父类相同,不仅仅是类型、数量,还包括显示形式)
  4. 警惕自增的陷阱
int count = 0;
for (int i=0;i<10;i++){
    count = count++;
}
System.out.println("count="+count);

上面这段代码的输出结果居然是:count=0
count++ 是一个表达式,是有返回值的,它的返回值就是count自加前的值。
Java对自加是这样处理的:
1、把count的值拷贝到一个临时变量区
2、对count变量加1
3、返回临时变量区的值

int count = 0;
for (int i=0;i<10;i++){
    count = ++count;
}
System.out.println("count="+count);
int count = 0;
for (int i=0;i<10;i++){
    count++;
}
System.out.println("count="+count);

上面两段代码的输出结果都是:count=10
8. 不要让旧语法困扰你
9. 少用静态导入
对于静态导入,一定要遵循两个规则:

  • 不使用*通配符,除非是导入静态常量类(只包含常量的类或接口)
  • 方法名是具有明确、清晰表象意义的工具类

滥用静态导入会使程序更难阅读,更难维护。静态导入后,代码中就不用再写类名了,静态属性和静态方法的表象意义可以被无限放大,让阅读者难以理解。
10. 不要在本类中覆盖静态导入的变量和方法
11. 养成良好习惯,显示声明UID
类实现Serializable接口的目的是为了可持久化,比如网络传输或本地存储,为系统的分布和异构部署提供先决支持条件。
serialVersionUID,也叫流标识符,即类的版本定义,它可以显式声明也可以隐式声明

private static final long serialVersionUID = 1L;

显式声明serialVersionUID可以避免对象不一致。
12. 避免用序列化类在构造函数中为不变量赋值
在序列化类中,不使用构造函数为final变量赋值(反序列化时构造函数不会执行)。
13. 避免为final变量复杂赋值
反序列化时final变量在以下情况下不会被重新赋值:

  • 通过构造函数为final变量赋值
  • 通过方法返回值为final变量赋值
  • final修饰的属性不是基本类型
  1. 使用序列化类的私有方法巧妙解决部分属性持久化问题
    部分属性持久化,可以通过把不需要持久化的属性加上transient关键字。
    实现了Serializable接口的类可以实现两个私有方法writeObject和readObject,以影响和控制序列化和反序列化的过程。
    (个人认为还是不要乱用这两个方法了)
  2. break万万不能忘
  3. 易变业务使用脚本语言编写
  4. 慎用动态编译
  5. 避免instanceof非预期结果
public class GenericClass<T> {
        public boolean isDateInstance(T t){
            return t instanceof Date;
        }
}

运行结果:

b1 : true
b2 : true
b3 : false
b5 : false
b6 : false
b8 : false
boolean b4 = 'A' instanceof Character;
这个编译不通过,因为'A'是一个char类型,也就是一个基本类型,不是一个对象,
instanceof只能用于对象的判断,不能用于基本类型的判断

boolean b5 = null instanceof Object;
boolean b6 = (String)null instanceof String;
若左操作数为null,直接返回false

boolean b7 = new Date() instanceof String;
编译不通过是因为Date类和String类没有继承和实现关系;

boolean b8 = new GenericClass<String>().isDateInstance("");
Java泛型是为编码服务的,在编译字节码时,T已经是Object类型了,传递的实参是String类型。
  1. 断言绝对不是鸡肋
    Java中的断言使用的是assert关键字,用法如下:
assert <布尔表达式>
assert <布尔表达式> : <错误信息>

布尔表达式为假时,抛出AssertionError,并附带了错误信息。
20. 不要只替换一个类
发布应用系统时禁止使用类文件替换方式,整体WAR包发布才是万全之策。

《编写高质量代码:改善Java程序的151个建议》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值