探索Java身体内部

            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

 1、内存分配: 
共有五个地方来存储数据,分别是: 
a.寄存器; 
b.堆栈(stack):局部变量; 
c.堆(heap):存放所有的Java对象;(编译器不需要知道存储的数据在堆里存活多长时间); 
d.常量存储:常量值通常直接存放在程序代码的内部; 
e.非RAM存储: 
   流对象:对象转化成字节流,通常被发送给另一台机器; 
   持久化对象:对象被存放于磁盘上。 
2.特例:基本类型 
创建一个并非是引用的“自动”变量。这个变量直接存储“值”,并置于堆栈中。 
Java SE5的自动包装功能将自动地将基本类型转换为包装器类型(Character ch = 'x';) 

 

Java提供了两个用于高精度计算的类:BigInteger和BigDecimal 

BigInteger: 
BigInteger:支持任意精度的整数。 
BigInteger(String val) 
          将 BigInteger 的十进制字符串表示形式转换为 BigInteger。 
BigInteger(String val, int radix) 
          将指定基数的 BigInteger 的字符串表示形式转换为 BigInteger。 

例如: 
BigInteger bigInt = new BigInteger("11",2); 
System.out.println("the big number is: " + bigInt); 
结果显示: 
the big number is: 3 

BigDecimal: 
BigDecimal:支持任何精度的定点数。 

网上摘录技巧集: 
1、当你在数据库里插入一条数据是6.00时,在显示时却是6.000000000000000000000。 
解决方法:使用BigDecimal要用String来够造,要做一个加法运算,需要先将两个浮点数转为String(如果利用double作为参数的构造函数,无法精确构造一个BigDecimal对象),然后构造成BigDecimal,在其中一个上调用add方法,传入另一个作为参数,然后把运算的结果(BigDecimal)再转换为浮点数。 
即: 
import java.math.BigDecimal; 
/** 
* 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精 
* 确的浮点数运算,包括加减乘除和四舍五入。 
*/ 
public class Arith{ //默认除法运算精度 
     private static final int DEF_DIV_SCALE = 10; //这个类不能实例化 
     private Arith(){ 
    } 
    /** 
     * 提供精确的加法运算。 
      * @param v1 被加数 
      * @param v2 加数 
      * @return 两个参数的和 
      */ 
    public static double add(double v1,double v2){ 
        //将传入的double转换为String 
        //如果利用double作为参数的构造函数,无法精确构造一个BigDecimal对象 
        BigDecimal b1 = new BigDecimal(Double.toString(v1)); 
        BigDecimal b2 = new BigDecimal(Double.toString(v2)); 
        //再将运算结果转换为double 
        return b1.add(b2).doubleValue(); 
    } 
    /** 
     * 提供精确的减法运算。 
      * @param v1 被减数 
      * @param v2 减数 
      * @return 两个参数的差 
      */ 
    public static double sub(double v1,double v2){ 
        BigDecimal b1 = new BigDecimal(Double.toString(v1)); 
        BigDecimal b2 = new BigDecimal(Double.toString(v2)); 
        return b1.subtract(b2).doubleValue(); 
    } 
    /** 
     * 提供精确的乘法运算。 
      * @param v1 被乘数 
      * @param v2 乘数 
      * @return 两个参数的积 
      */ 
    public static double mul(double v1,double v2){ 
        BigDecimal b1 = new BigDecimal(Double.toString(v1)); 
        BigDecimal b2 = new BigDecimal(Double.toString(v2)); 
        return b1.multiply(b2).doubleValue(); 
    } 
    /** 
     * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 
      * 小数点以后10位,以后的数字四舍五入。 
      * @param v1 被除数 
      * @param v2 除数 
      * @return 两个参数的商 
      */ 
    public static double div(double v1,double v2){ 
        return div(v1,v2,DEF_DIV_SCALE); 
    } 
    /** 
     * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 
      * 定精度,以后的数字四舍五入。 
      * @param v1 被除数 
      * @param v2 除数 
      * @param scale 表示表示需要精确到小数点以后几位。 
      * @return 两个参数的商 
      */ 
    public static double div(double v1,double v2,int scale){ 
        if(scale<0){ 
            throw new IllegalArgumentException( 
                "The scale must be a positive integer or zero"); 
        } 
        BigDecimal b1 = new BigDecimal(Double.toString(v1)); 
        BigDecimal b2 = new BigDecimal(Double.toString(v2)); 
        return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); 
    } 
    /** 
     * 提供精确的小数位四舍五入处理。 
      * @param v 需要四舍五入的数字 
      * @param scale 小数点后保留几位 
      * @return 四舍五入后的结果 
      */ 
    public static double round(double v,int scale){ 
        if(scale<0){ 
            throw new IllegalArgumentException( 
                "The scale must be a positive integer or zero"); 
        } 
        BigDecimal b = new BigDecimal(Double.toString(v)); 
        BigDecimal one = new BigDecimal("1"); 
        return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); 
    } 
}; 
2、因此,使用这个类BigDecimal,需要注意在构造方法中如果传入double,那么不能保证他的精确程度。 
如: 
           BigDecimal bigDec = new BigDecimal(6.217); 
BigDecimal bigDecAdd = new BigDecimal(6.3229); BigDecimal bigDecResult = bigDec.add(bigDecAdd); System.out.println("the big decimal is: " + bigDecResult); 
结果却是: 
the big decimal is: 12.53989999999999938040673441719263792037963867187500 
如果传入的是String类型,则: 
the big decimal is: 12.5399

 

2:

 

 

        Integer a = 127;
        Integer b = 127;
		Integer a2 = 128;
		Integer b2 = 128;
		System.out.println(a == b);// true
		System.out.println(a2 == b2);//false

 后面的注释就是结果,为什么?请看源码

 

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

 看IntegerCache ,它是Integer的一个私有静态内部类,对Integer进行缓存处理

 

 

    private static class IntegerCache {
        static final int high;
        static final Integer cache[];

        static {
            final int low = -128;

            // high value may be configured by property
            int h = 127;
            if (integerCacheHighPropValue != null) {
                // Use Long.decode here to avoid invoking methods that
                // require Integer's autoboxing cache to be initialized
                int i = Long.decode(integerCacheHighPropValue).intValue();
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - -low);
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

        private IntegerCache() {}
    }
 

所以我们进行对象比较时最好还是使用equals,便于按照自己的目的进行控制。

注意静态代码块的代码:

 

            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

  由于cache[]在IntegerCache类中是静态数组,也就是只需要初始化一次,即static{......}部分,

所以,如果Integer对象初始化时是-128~127的范围,就不需要再重新定义申请空间,
都是同一个对象---在IntegerCache.cache中,这样可以在一定程度上提高效率。

 

顺便把chm版本的Thigking in Java传上来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值