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. 如何管理Session(防止恶意共享账号)——理论篇

    目录 知识要求 背景 技术原理 如何管理Session remember me的问题 附录 知识要求 有一定的WEB后端开发基础,熟悉Session的用法,以及与Redis.Database的配合 本 ...

  2. asp.net core 2.0集成signalr

    在博客园也很多年了,一直未曾分享过什么东西,也没有写过博客,但自己也是汲取着博客园的知识成长的: 这两天想着不能这么无私,最近.NET CORE貌似挺流行的,闲来无事也自己搞了个asp.net cor ...

  3. 如何在 Centos7 中安装 nginx

    1. 添加 nginx 的 yum 源(官网安装说明) vi /etc/yum.repos.d/nginx.repo 在该文件中添加如下内容: [nginx]name=nginx repobaseur ...

  4. [模拟]P1202 [USACO1.1]黑色星期五Friday the Thirteenth

    原题 解析: 坑 其实.样例的部分是从周六~周五输出的,习惯不同吧..这里考虑到从这个月的13号到下一个月的13号所花天数为这个月的天数,然后愉快的判断一下闰年即可.这里的周一~周日编号为0~6,一月 ...

  5. BOM物料清单在输入用料计划时快捷选择物料没有带出单位

    问题: 在新增BOM物料清单时,输入用料计划,快捷选择物料没有带出单位,但是从清单查找里面选择物料,是可以自动带出单位的. 原因分析查找: 1.这是个自定义单据,到tools工具上查看相关设置,看清单 ...

  6. wamp环境下如何安装redis扩展

    Redis安装 wamp环境安装redis扩展 首先在自己本地项目中phpinfo(); 查看php版本; (php版本是5.5, ts-vcll表示MSVC11 (Visual C++ 2012), ...

  7. 数据库—Mysql

    今天跟大家来聊聊Mysql,首先介绍一下它的历史: Mysql是一个关系型数据库管理系统,最先由瑞典的MySQL AB公司开发,后来被sun公司收购,后因sun公司又被Oracle公司收购,致使MyS ...

  8. Glance 镜像服务群集

    #Glance 镜像服务群集 openstack pike 部署 目录汇总 http://www.cnblogs.com/elvi/p/7613861.html#4.Glance 镜像服务群集 ##. ...

  9. 深入讲解HashMap原理

    1.    HashMap概述: HashMap是基于哈希表的Map接口的非同步实现.此实现提供所有可选的映射操作,并允许使用null值和null键.此类不保证映射的顺序,特别是它不保证该顺序恒久不变 ...

  10. 怎么配置Jupyter Notebook默认启动目录?

    前言 系统环境:win10 x64:跟环境也没啥关系,在LInux下也一样... 前段时间重换了系统后,发现Jupyter Notebook的默认启动目录不太对呀,所以,就翻到了以前的笔记,还是记在这 ...