20191127-编写高质量代码:2-基本类型

Java中的基本数据类型有8个:byte、short、int、long、float、double、boolean、char

  1. 用偶判断,不用奇判断
String str = 1%2==1?"奇数":"偶数";
System.out.println("1 是" + str);

str = 2%2==1?"奇数":"偶数";
System.out.println("-2 是" + str);

str = -1%2==1?"奇数":"偶数";
System.out.println("-1 是" + str);

str = -2%2==1?"奇数":"偶数";
System.out.println("-2 是" + str);

运行结果:
1 是奇数
2 是偶数
-1 是偶数
-2 是偶数

-1 是偶数 ???
需要了解Java取余(%)算法,模拟代码如下:

// dividend:被除数 divisor:除数
public static int remainder(int dividend,int divisor){
    return dividend - dividend/divisor * divisor
}

当输入-1时,-1 - -1/2*2 = -1 ,结果为-1,不等1
因此,要修改判断是否为偶数:

i%2 == 0?"偶数":"奇数";
  1. 用整数类型处理货币
    对于货币计算推荐
    1、使用BigDecimal
    2、使用整型(把参与运算的值扩大100倍,并转变为整型,展现的时候再缩小100倍)
  2. 不要让类型默默转换
    Java是先运算再进行类型转换的,基本类型转换时,使用主动声明方式,减少不必要的bug
  3. 边界,边界,还是边界
    临界测试,校验边界参数
  4. 不要让四舍五入亏了一方
    根据不同的场景,慎重选择不同的舍入模式,以提高项目的精准度,减少算法损失。
    BigDecimal类提供了7种舍入方式:
// 远离0方向舍入,向绝对值最大的方向舍入,只要舍弃位非0即进位
public final static int ROUND_UP =           0;

//趋向0方向舍入,向绝对值最小的方向舍入,所有的位都舍弃,不存在进位情况
public final static int ROUND_DOWN =         1;

//向正无穷方向舍入
//如果是正数,舍入行为类似于ROUND_UP
//如果是负数,舍入行为类似于ROUND_DOWN
public final static int ROUND_CEILING =      2;

//向负无穷方向舍入
//如果是正数,舍入行为类似于ROUND_DOWN
//如果是负数,舍入行为类似于ROUND_UP
public final static int ROUND_FLOOR =        3;

//最近数字舍入(5进) ,经典的四舍五入模式
public final static int ROUND_HALF_UP =      4;

//最近数字舍入(5舍)
public final static int ROUND_HALF_DOWN =    5;

//银行家算法
public final static int ROUND_HALF_EVEN =    6;

//断言请求的操作具有精确的结果,因此不需要舍入。
//如果对获得精确结果的操作指定此舍入模式,则抛ArithmeticException。
public final static int ROUND_UNNECESSARY =  7;
  1. 提防包装类型的null值
    包装类型参与运算时,要做null值校验
  2. 谨慎包装类型的大小比较
  3. 优先使用整型池
    通过包装类的valueOf生成包装实例可以显著提高空间和时间性能。
static final int low = -128;
static final int high;
static final Integer cache[];

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

cache[]IntegerCache内部类的一个静态数组,容纳-128到127之间的Integer对象(-128,128),即[-127,127]。
通过valueOf产生包装对象时,如果int参数在[-127,127]范围内,直接从整型池中获取,否则再通过new Integer(i)生成包装对象。
29. 优先选择基本类型

f(140);
f(Integer.valueOf(140));

public static void f(long l){
    System.out.println("基本类型的方法被调用");
}
public static void f(Long l){
    System.out.println("包装类型的方法被调用");
}

运行结果:
基本类型的方法被调用
基本类型的方法被调用

编译通过了,自动装箱有一个很重要的原则:基本类型可以先加宽,再转变成宽类型的包装类型,但不能直接转变成宽类型的包装类型。(这里说的是自动转换)

int i = 140;
f(i);

public static void f(Long l){
    System.out.println("包装类型的方法被调用");
}

上面这段代码编译就不会通过
在这里插入图片描述
因为i是一个int类型,不能自动转换为Long型;修改成下面的代码就行了。
在这里插入图片描述
重申:基本类型优先考虑。
30. 不要随便设置随机种子
在java项目中通常通过Math.random方法或Random类来获得随机数的。

Random r = new Random(100);
System.out.println("第一个随机数:"+r.nextInt());
System.out.println("第二个随机数:"+r.nextInt());
System.out.println("第三个随机数:"+r.nextInt());

输出结果:
第一个随机数:-1193959466
第二个随机数:-1139614796
第三个随机数:837415749

计算机不同输出的随机数不同,但有一点是相同的:在同一台机器上,甭管运行多少次,所打印的随机数都是相同的。也就是第一次运动打印的是这个随机数,第二次运行打印的还是这个随机数。
这是因为产生随机数的种子被固定了,在Java中,随机数的产生取决于种子,随机数和种子之间的关系遵从以下两个规则:

  • 种子不同,产生不同的随机数
  • 种子相同,即使实例不同也产生相同的随机数
// Random类的默认种子(无参构造方法)
//System.nanoTime(),操作系统读取的纳秒值每次读取的肯定不同,随机数自然也不同了
public Random() {
    this(seedUniquifier() ^ System.nanoTime());
}

若非必要,不要设置随机数种子。

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

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值