java.lang.Boolean

     public static int hashCode(boolean value) {
return value ? 1231 : 1237;
}

JDK 1.8新增一个hashCode方法,true的hashCode为1231,false的hashCode为1237, why?

https://stackoverflow.com/questions/3912303/boolean-hashcode

     public static int compare(boolean x, boolean y) {
return (x == y) ? 0 : (x ? 1 : -1);
}

在类中定义了两个public static final的变量,在创建Boolean对象的时候可以

     public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);

在创建Boolean对象的时候整个项目如果都是采用valueOf方法来创建,则整个项目就都会使用的这两个对象了。

     public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
public static Boolean valueOf(String s) {
return parseBoolean(s) ? TRUE : FALSE;
}

剩下的Byte、Short、Integer、Long、Float、Double都是继承自Number类,除此之外还有BigDecimal和BigInteger类。

下面总结下基础数据类型的数值范围

数据类型 字节 范围
boolean 1 true或false
char 2 从字符型对应的整型数来划分,其表示范围是0~65535 
byte 1 -128~127
short 2 -32768~32767
int 4 -2147483648~2147483647 (-2^31 ~ 2^31-1)
long 8 -9223372036854775808 ~ 9223372036854775807
float 4 -3.4E38~3.4E38 
double 8 -1.7E308~1.7E308

java.lang.Integer

     public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
char[] buf = new char[size];
getChars(i, size, buf);
return new String(buf, true);
} static void getChars(int i, int index, char[] buf) {
int q, r;
int charPos = index;
char sign = 0; if (i < 0) {
sign = '-';
i = -i;
} // Generate two digits per iteration
while (i >= 65536) {
q = i / 100;
// really: r = i - (q * 100);
r = i - ((q << 6) + (q << 5) + (q << 2));
i = q;
buf [--charPos] = DigitOnes[r];
buf [--charPos] = DigitTens[r];
} // Fall thru to fast mode for smaller numbers
// assert(i <= 65536, i);
for (;;) {
q = (i * 52429) >>> (16+3);
r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
buf [--charPos] = digits [r];
i = q;
if (i == 0) break;
}
if (sign != 0) {
buf [--charPos] = sign;
}
} final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE }; // Requires positive x
static int stringSize(int x) {
for (int i=0; ; i++)
if (x <= sizeTable[i])
return i+1;
} final static char [] DigitTens = {
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
'2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
'3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
'4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
'5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
'6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
'7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
'8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
'9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
} ; final static char [] DigitOnes = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
} ;

感觉这个toString方法实现的太巧妙了,为了减少运算真是无所不用其极,忍不住将这一整段的代码都贴出来了。

stringSize方法是计算整个整数x有多少个字符,如此就可以预先计算出一个整型转换为字符数组要提前分配多少空间。这个方法的实现是通过比较大小实现的,预先定义好一个从小到大的数组sizeTable,配合下标确定size。

getChars方法是将整型i转换为一个字符数组buf,其中index参数是整型i中包含的字符数,也即buf需要多少长度来存储转换后的整型。在方法中如果整型i >= 65536,则通过q = i/100;  r = i - q * 100;的方式将数字拆分成两个部分,其中r为i的前两位。高潮来了,看他怎么实现的获取这两位的字符的,竟然用数组查询的方式!当然,这是个while循环,会一直处理直到i<65536。再看下for循环中的将小于65536的数字转换为字符数组。q = (i * 52429) >>> (16+3) 这一句其实是个除以10的操作,那为什么要用52429呢?524288 = 2^19, i * 52429 然后无符号右移19位,相当于52429/2^19 = 0.100000381,近似是等于i/10(移位运算远比除法快,也是一种优化策略)。那为什么要选择2^19呢?参考了下知乎的回答:java源码中Integer.class中有个getChars方法,里面有个52429是怎么确定的?。然后我又计算了下2^20和2^21,结果竟然等于2^19,然后2^22精度就更高一些,但也没有太大的必要了。

     private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[]; static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h; cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
} private IntegerCache() {}
} public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

通过IntegerCache内部类将常用的整数存储起来,当使用valueOf的方式构造Integer对象的时候,会直接从IntegerCache中取值。IntegerCache的最小值固定为-128,最大值可以通过java.lang.Integer.IntegerCache.high设置。

java.lang.Byte

在Byte类中同样是有个ByteCache缓存的缓存了从-128到正的127的byte,也就是byte的取值范围都被缓存了。通过下面的valueOf就可以使用到ByteCache类中的缓存值了。

     public static Byte valueOf(byte b) {
final int offset = 128;
return ByteCache.cache[(int)b + offset];
}

Byte中的很多函数都是将byte转换成int然后再操作的。

java.lang.Short

Short类中也同样有个ShortCache缓存,缓存了从-128到127的整数,不过要注意short是两个字节的。同样的使用ValueOf可以使用缓存中的内容。

     private static class ShortCache {
private ShortCache(){} static final Short cache[] = new Short[-(-128) + 127 + 1]; static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Short((short)(i - 128));
}
} public static Short valueOf(short s) {
final int offset = 128;
int sAsInt = s;
if (sAsInt >= -128 && sAsInt <= 127) { // must cache
return ShortCache.cache[sAsInt + offset];
}
return new Short(s);
}
     public static short reverseBytes(short i) {
return (short) (((i & 0xFF00) >> 8) | (i << 8));
}

在Short类中还有个reverseBytes函数,将高位字节和低位字节互换位置。不知道这样做有什么用途。

java.lang.Long

同样的在Long类中toString方法实现类似于Integer中的toString方法,不再赘述。

在缓存方面,Long类中同样有个LongCache缓存类,缓存了-128L~127L的Long对象,通过valueOf可以直接获取缓存中的类对象。

在JDK 1.8中,增加了以下几个方法

     // 比较两个long
// @since 1.7
public static int compare(long x, long y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
} // 比较两个unsigned long
// @since 1.8
public static int compareUnsigned(long x, long y) {
return compare(x + MIN_VALUE, y + MIN_VALUE);
} // 除法运算,结果是除得的结果,余数采用remainderUnsigned获得
// @since 1.8
public static long divideUnsigned(long dividend, long divisor) {
if (divisor < 0L) { // signed comparison
// Answer must be 0 or 1 depending on relative magnitude
// of dividend and divisor.
return (compareUnsigned(dividend, divisor)) < 0 ? 0L :1L;
} if (dividend > 0) // Both inputs non-negative
return dividend/divisor;
else {
/*
* For simple code, leveraging BigInteger. Longer and faster
* code written directly in terms of operations on longs is
* possible; see "Hacker's Delight" for divide and remainder
* algorithms.
*/
return toUnsignedBigInteger(dividend).
divide(toUnsignedBigInteger(divisor)).longValue();
}
} // 除法运算,结果是余数
// @since 1.8
public static long remainderUnsigned(long dividend, long divisor) {
if (dividend > 0 && divisor > 0) { // signed comparisons
return dividend % divisor;
} else {
if (compareUnsigned(dividend, divisor) < 0) // Avoid explicit check for 0 divisor
return dividend;
else
return toUnsignedBigInteger(dividend).
remainder(toUnsignedBigInteger(divisor)).longValue();
}
}

另外增加了sum方法,如下面的代码,代码中并没有考虑溢出问题,所以谨慎调用。

     public static long sum(long a, long b) {
return a + b;
}

java.lang.Double

     public boolean equals(Object obj) {
return (obj instanceof Double)
&& (doubleToLongBits(((Double)obj).value) ==
doubleToLongBits(value));
} public static long doubleToLongBits(double value) {
long result = doubleToRawLongBits(value);
// Check for NaN based on values of bit fields, maximum
// exponent and nonzero significand.
if ( ((result & DoubleConsts.EXP_BIT_MASK) ==
DoubleConsts.EXP_BIT_MASK) &&
(result & DoubleConsts.SIGNIF_BIT_MASK) != 0L)
result = 0x7ff8000000000000L;
return result;
}

在Double类中,重载了equals方法,其中的doubleToRawLongBits是个native方法。

java.lang.Float

Float源码和Double类方法差不多。就这样结束吧。

java.lang基础数据类型boolean、char、byte、short、int、long、float、double (JDK1.8)的更多相关文章

  1. 常用类一一基本数据类型的包装类(WrapperClass)一一Byte Short nteger Long Float Double Character Boolean

    为什么需要包装类? JAVA是支持跨平台的.可以在服务器 也可以在手机上运行 基本数据类型 在栈中  效率更高 包装类 将数据类型转换成对象 在 堆中  利于操作 package cn.bjsxt.w ...

  2. Python入门篇-基础数据类型之整型(int),字符串(str),字节(bytes),列表(list)和切片(slice)

    Python入门篇-基础数据类型之整型(int),字符串(str),字节(bytes),列表(list)和切片(slice) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Py ...

  3. java.lang.NullPointerException: Attempt to invoke virtual method 'int com.example.xxx.Json.NewsBean.getError_code()' on a null object reference错误解决

    AS在运行的过程中出现了错误: java.lang.NullPointerException: Attempt to invoke virtual method 'int com.example.xx ...

  4. Java中基本数据类型byte,short,char,int,long,float,double 取值范围

    部分内容转自:java 彻底理解 byte char short int float long double 首先说byte: 这段是摘自jdk中 Byte.java中的源代码: /** * A co ...

  5. java之基础数据类型学习————(一)

    JAVA数据类型: 总结来说,java的基本数据类型分为 四类八种 • 第一类:整数类型:byte.short.int.long • 第二类:浮点型:float.double • 第三类:字符类型:c ...

  6. java的基础数据类型

    Java 里面的数据类型从大的方面分为两类,一是基本数据类型,一是引用类型.基本的JAVA 数据类型层次图如下: Java 中的基本数据类型可分为四种:(1)逻辑型:boolean(2)文本型:cha ...

  7. Java语言基础——数据类型与运算符

    标识符: 1.组成元素由字母.数字.下划线.美元符号($) 2.标识符不能以数字开头 3.标识符严格区分大小写 4.标识符的命名要有意义(见名知意) 注释: 1.单行注释 // 2.多行注释 /* 注 ...

  8. java整型byte,short,int,long取值范围大小

     byte 1个字节 short 2个字节 int 4个字节long 8 个字节 varchar 可变长度的非Unicode数据,最长为8000个字符nvarchar 可变长度Unicode数据,最长 ...

  9. Java - 关于基础数据类型的形参和返回值

    1. 当基础数据类型被当作形参时,最好使用其包装类,因为这样可方便调用者传参(基础数据类型亦或是其包装类都可)   2. 当基础数据类型被当作返回值时,最好使用原型,因为这样可以方便调用者接收返回值( ...

随机推荐

  1. Java compareTo() 方法

    以金钱实交(realPay),和使用预存(usePurseFee)为例: if ( realPay.compareTo(usePurseFee) <=0) { XXXXXXX; }else { ...

  2. java面向对象整理

    1.局部变量与全局变量的区别 区别一:定义的位置不同 定义在类中的变量是成员变量 定义在方法中或者{}语句里面的变量是局部变量定义 区别二:在内存中的位置不同 成员变量存储在对内存的对象中 局部变量存 ...

  3. js 图片转换为base64

    <input id="file" type="file"> <img id="img" style="max-h ...

  4. Python 简单理解多线程

    进程,是一个或多个线程的集合,每个进程在内存中是相对独立的. 线程,是计算机最小的运算单元,每个进程至少要有一个线程,多个线程时,每个线程间之间共享内存. 分别举例常规运行和多线程运行: 0)常规运行 ...

  5. [最短路]P1119 灾后重建

    题目背景 B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重建完成的村庄的公路才能 ...

  6. Linux下执行ls命令提示CMake Error错误

    一.系统环境 Fedora10 二.出错情况 执行ls命令出现如下错误提示: CMake Error: The source directory "/etc/--color=auto&quo ...

  7. 并行设计模式(二)-- Master-Worker模式

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Mast ...

  8. js笔记(制作一个简单的计数器)

    首先编写静态页中的按钮: <input  id="result" type="button" value="该程序已经运行了0秒!"/ ...

  9. Cannot load browser "PhantomJS": it is not registered! Perhaps you are missing some plugin? 测试安装遇到的BUG

    安装了半天phantomjs就是安装不好,后面想了个死办法,http://phantomjs.org/download.html这个网址下先去下载好 phantomjs-2.1.1-windows.z ...

  10. 使用python

    最近看视频学习,老师布置了个作业,关于如何使用python将多个excel进行合并,老师写的代码我感觉比较复杂,下面是我自己改良之后较简单的方式. 实现这个功能主要有两种方法,一种是用xlwd,xls ...