基本的数据类型分析----java.lang.Number类及其子类分析

本文转自http://blog.csdn.net/springcsc1982/article/details/8788345 感谢作者

编写了一个测试程序,如下:

int a = 1000, b= 1000;

System.out.println(a == b);

Integer c = 1000, d = 1000;

System.out.println(c == d);

Integer e = 100,h = 100;

System.out.println(e == h);

得出了一个惊人的结果,结果为:true,false,true,第一个语句好说,比较的是值,所以结果是true,第二个与第三个,区别就只有数值不同,为什么会得出不同的结果?于是查看源代码寻找答案,原来,所有的数字类都存在缓存机制,只要是-128至127之间的数字都会被缓存,在这个范围之外的数据,则会生成新的对象。

由于程序运行得到的结果较为奇怪,于是开始了寻找答案之路,主要涉及到的类包括:

Java.lang.Integer、java.lang.Number,另外由于Number是所有数值类的父类,所以将其相关的类都学习一遍,

包括

java.lang.Byte,

java.lang.Double,

java.lang.Float,

java.lang.Long,

java.lang.Short

以上各类的关系如下:

从上图中看出,这些数据类都是继承自Number类,Number是一个抽象类,包含了各种数据转换的方法,即转换为各种类型的数据:

public abstract int intValue();

public abstract long longValue();

public abstract float floatValue();

public abstract double doubleValue();

public byte byteValue()

public short shortValue()

我们打开Integer来分析一下:

private static class IntegerCache{

private IntegerCache(){}

static final Integer cache[] = new Integer[-(-128) + 127 + 1];

static {//静态代码块,虚拟机装载该类时调用

for(int i = 0; i < cache.length; i++)

cache[i] = new Integer(i - 128);

}

}

public static Integer valueOf(int i) {

final int offset = 128;

if (i >= -128 && i <= 127) { // must cache

return IntegerCache.cache[i + offset];//返回缓存中的对象

}

return new Integer(i);//生成新的对象

}

发现Integer类里面包括了一个内部类,在该类中定义一个缓存数组,在静态代码块中生成一个缓存,并存储256个Integer对象。当传递进来的值在-128至127之间,系统自动获取缓存中的对象,当不在这个区间,系统即生成新的对象,所以,执行代码Integer c = 1000, d = 1000;  System.out.println(c== d);时,系统会自动生成两个新对象,自然结果为false,当a=100,b=100时,则打印出来的结果为true.

同理,Long、Float、Double、Byte、Short也存在内部的缓存类LongCache、FloatCache、DoubleCache、ByteCache、ShortCache。

我们再来看看Integer类的一些属性与方法:

Size属性:即比特数,Integer为32位,Double为64位,Long也是64位,Float为32个位,Short为16位,Byte为8位

public static final Class<Integer>  TYPE = (Class<Integer>) Class.getPrimitiveClass("int");

Class.getPrimitiveClass("int"):获取虚拟机级别的int类型,说明Integer与int还是有很大区别的,int是虚拟机内部的类型,而Integer不过是在这个类型的基础上进行封装。

toString(int i, int radix)   根据radix进制将数字转换为字符串

toHexString    按照16进制输出

toOctalString  按照8进制输出

toBinaryString 按照二进制输出

stringSize       返回十进制的X位数

parseInt(String s, int radix)    将字符串转换为X进制的整数

parseInt(String s)   默认为十进制的整数

valueOf(String s, int radix)   将字符串转换为X进制的整数,只是返回时new了一个Integer

valueOf(String s,) 默认为十进制的整数,只是返回时new了一个Integer

equals     重写OBJECT的,判断值是否相同,而不是判断对象

getInteger       返回系统属性的数字值,这个方法貌似存在问题

decode    根据字符串解析为Integer类型,字符串可能为X进制

compareTo     比较两个值的大小,分别返回0,1,-1

看完了Integer类,其他类基本是相同的,其他类相关的方法如下:

Byte类,对应虚拟机的byte类

ByteCache      也是在-128到127之间

parseByte       根据X进制转换为Byte类型

valueOf   根据X进制转换为Byte类型,并new一个新的Byte

public static Byte decode(String nm)    根据字符串转换为Byte

compareTo     比较,并返回两个值的差

Double类,对应虚拟机的double

SIZE=64 64个比特,即8个字节

isInfinite  是否无限大无限小

isNaN     判断两个值是否相等

doubleToLongBits   long与double都是64位,这个函数是将double转换为long ,因为在JAVA里面,double无法做位运算

longBitsToDouble native方法,应该是bit转为DOUBLE

Float类,相当于虚拟机的float   32位

floatToRawIntBits  native方法,float转为int

LongCache,缓存类

highestOneBit  返回Long值的最高一位

lowestOneBit  返回Long值的最低一位

bitCount  返回指定 long 值的二进制补码表示形式中的 1 位的数量

Short相当于虚拟机内部的short 16位,两个字节

时间: 2024-10-29 19:07:32

基本的数据类型分析----java.lang.Number类及其子类分析的相关文章

java.lang的类

java.lang的类分为以下几类: 1 Object.Class Object类是类层次结构的根,所有的java类均直接或间接继承于Object. Class类的实例表示正在运行的应用程序中的类. 2 包装器 包装器类有8种:Boolean.Character.Byte.Short.Integer.Long.Float.Double. 后6种继承自java.lang.Number类,该类实现了java.io.Serializable接口. 3 数学计算与字符串处理 Math类提供了常见的数学函

分析java.lang.NullPointerException thrown in RelativeLayout measure()

典型重现环境 机型: Sony Ericsson Android version: 2.3.4 StackTrace: E/AndroidRuntime( 3579): FATAL EXCEPTION: main E/AndroidRuntime( 3579): java.lang.NullPointerException E/AndroidRuntime( 3579): at android.widget.RelativeLayout.onMeasure(RelativeLayout.java

There is no getter for property named &#39;*&#39; in &#39;class java.lang.String&#39;之源码分析

There is no getter for property named '*' in 'class java.lang.String',此错误之所以出现,是因为mybatis在对parameterType="String"的sql语句做了限制,假如你使用<when test="username != null">这样的条件判断时,就会出现该错误,不过今天我们来刨根问底一下. 一.错误再现 想要追本溯源,就需要错误再现,那么假设我们有这样一个sql查询

深入研究java.lang.ProcessBuilder类

 深入研究java.lang.ProcessBuilder类 一.概述       ProcessBuilder类是J2SE 1.5在java.lang中新添加的一个新类,此类用于创建操作系统进程,它提供一种启动和管理进程(也就是应用程序)的方法.在J2SE 1.5之前,都是由Process类处来实现进程的控制管理.      每个 ProcessBuilder 实例管理一个进程属性集.它的start() 方法利用这些属性创建一个新的 Process 实例.start() 方法可以从同一实例重复

Java 线程--继承java.lang.Thread类实现线程

现实生活中的很多事情是同时进行的,Java中为了模拟这种状态,引入了线程机制.先来看线程的基本概念. 线程是指进程中的一个执行场景,也就是执行流程,进程和线程的区别: 1.每个进程是一个应用程序,都有独立的内存空间. 2.同一个进程中的线程共享其进程中的内存和资源. (共享的内存是堆内存和方法区内存,栈内存不共享,每个线程有自己的栈内存) 我们还需要了解以下基本内容: 1.什么是进程? 一个进程对应一个应用程序.例如:在Windows操作系统启动word就表示启动了一个进程.在Java开发环境下

java.lang.Void类源码解析_java - JAVA

文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 在一次源码查看ThreadGroup的时候,看到一段代码,为以下: /* * @throws NullPointerException if the parent argument is {@code null} * @throws SecurityException if the current thread cannot create a * thread in the specified thread grou

浅析Java.lang.ProcessBuilder类

最近由于工作需要把用户配置的Hive命令在Linux环境下执行,专门做了一个用户管理界面特地研究了这个不经常用得ProcessBuilder类.所以把自己的学习的资料总结一下. 一.概述      ProcessBuilder类是J2SE 1.5在java.lang中新添加的一个新类,此类用于创建操作系统进程,它提供一种启动和管理进程(也就是应用程序)的方法.在J2SE 1.5之前,都是由Process类处来实现进程的控制管理.      每个 ProcessBuilder 实例管理一个进程属性

深入研究java.lang.Runtime类

深入研究java.lang.Runtime类 一.概述      Runtime类封装了运行时的环境.每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接.      一般不能实例化一个Runtime对象,应用程序也不能创建自己的 Runtime 类实例,但可以通过 getRuntime 方法获取当前Runtime运行时对象的引用.      一旦得到了一个当前的Runtime对象的引用,就可以调用Runtime对象的方法去控制Java虚拟机的状态和行为.

浅析Java.lang.Process类

一.概述      Process类是一个抽象类(所有的方法均是抽象的),封装了一个进程(即一个执行程序).      Process 类提供了执行从进程输入.执行输出到进程.等待进程完成.检查进程的退出状态以及销毁(杀掉)进程的方法.      ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机进程,并返回 Process 子类的一个实例,该实例可用来控制进程并获取相关信息. 创建进程的方法可能无法针对某些本机平台上的特定进程很好地工作,比如,本机窗口