深入学习java源码之Long.valueOf()与Long.doubleValue()
在Long的源代码中,可以找到LongCache内部类的代码:
private static class LongCache {
private LongCache(){}
static final Long cache[] = new Long[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Long(i - 128);
}
}
从LongCache的代码可以很容易看出来,在类初始化的时候,便生成了一个final的static的Long类型数组,数组的范围是-128到127。
Long类型的valueOf方法代码如下:
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}
从以上两个代码中不难发现,当外部程序调用了valueOf方法时,Java先判断欲生成的Long对象是否在LongCache.cache数组的范围内,如果是,则直接返回已经存在cache数组的Long对象引用。根据之前对String类型的研究,这应该是通过重复使用对象的引用,从而实现了较高的性能和较少的内存消耗。此外,经过测试,通过“Long = long”方式生成的Long对象,称为自动封箱,也有相同的逻辑。
所以也就不难知道,当实际的long大小超过正数127时,判断两个封装类==时,会返回false。
另外一种情况,通过new方式生成的两个等值的对象,是否会有相同的效果呢?经过测试,是否定的。两次new出来的对象,都是在内存中新划分区域生成的对象,除非重写方法,否则是绝对不能通过==进行比较的。
for(;;)和while(true)的区别
“死循环”有两种写法:for(;;)和while(true),
编译前 编译后
while (1); mov eax,1
test eax,eax
je foo+23h
jmp foo+18h
编译前 编译后
for (;;); jmp foo+23h
一目了然,for (;;)指令少,不占用寄存器,而且没有判断跳转,比while (1)好。
也就是说两者在在宏观上完全一样的逻辑,但是底层完全不一样,for相对于来说更加简洁明了。
Modifier and Type | Method and Description |
---|---|
static int | bitCount(long i) 返回指定的long值的二进制补码二进制表示中的 |
byte | byteValue() 返回此值 |
static int | compare(long x, long y) 数值比较两个 |
int | compareTo(Long anotherLong) 以数字比较两个 |
static int | compareUnsigned(long x, long y) 比较两个 |
static Long | decode(String nm) 将 |
static long | divideUnsigned(long dividend, long divisor) 返回将第一个参数除以秒的无符号商,其中每个参数和结果被解释为无符号值。 |
double | doubleValue() 返回此值 |
boolean | equals(Object obj) 将此对象与指定的对象进行比较。 |
float | floatValue() 返回此值 |
static Long | getLong(String nm) 确定 |
static Long | getLong(String nm, long val) 确定 |
static Long | getLong(String nm, Long val) 以指定的 |
int | hashCode() 返回这个 |
static int | hashCode(long value) 返回一个 |
static long | highestOneBit(long i) 返回一个 |
int | intValue() 在 |
long | longValue() 返回此值 |
static long | lowestOneBit(long i) 返回一个 |
static long | max(long a, long b) 返回两个 |
static long | min(long a, long b) 返回两个 |
static int | numberOfLeadingZeros(long i) 返回的最高阶的(“最左边的”)中所指定的二进制补码表示的一个位前述零个比特的数量 |
static int | numberOfTrailingZeros(long i) 返回零位以下最低阶(“最右边的”)的数量在指定的二进制补码表示的一个位 |
static long | parseLong(String s) 将字符串参数解析为带符号的十进制 |
static long | parseLong(String s, int radix) 将字符串参数解析为由第二个参数指定的基数中的带符号的 |
static long | parseUnsignedLong(String s) 将字符串参数解析为无符号十进制 |
static long | parseUnsignedLong(String s, int radix) 将字符串参数解析为第二个参数指定的基数中的无符号 |
static long | remainderUnsigned(long dividend, long divisor) 返回无符号余数,将第一个参数除以秒,其中每个参数和结果被解释为无符号值。 |
static long | reverse(long i) 返回由指定的二进制补码表示反转位的顺序而获得的值 |
static long | reverseBytes(long i) 返回反转指定的二进制补码表示的字节顺序而获得的值 |
static long | rotateLeft(long i, int distance) 返回通过旋转指定的位数剩下的指定 |
static long | rotateRight(long i, int distance) 返回通过旋转指定的二的补码的二进制表示而得到的值 |
short | shortValue() 在 |
static int | signum(long i) 返回指定的 |
static long | sum(long a, long b) 根据+操作符将两个 |
static String | toBinaryString(long i) 返回 |
static String | toHexString(long i) 返回 |
static String | toOctalString(long i) 返回 |
String | toString() 返回 |
static String | toString(long i) 返回 |
static String | toString(long i, int radix) 返回由第二个参数指定的基数中的第一个参数的字符串表示形式。 |
static String | toUnsignedString(long i) 将参数的字符串表示形式返回为无符号十进制值。 |
static String | toUnsignedString(long i, int radix) 以第二个参数指定的基数中的无符号整数值返回第一个参数的字符串表示形式。 |
static Long | valueOf(long l) 返回一个 |
static Long | valueOf(String s) 返回一个 |
static Long | valueOf(String s, int radix) 返回一个 |
java源码