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{......}部分,
顺便把chm版本的Thigking in Java传上来