Java中基本数据类型和包装类

参考:深入剖析Java中的装箱和拆箱
Java中基本数据类型和包装类互转中 缓冲机制的使用
java学习笔记:装箱和拆箱,包装器和缓冲池 
Java 各 类型数据在内存中分配情况详解

一 java内存分配

这里只是在网上找的一些资料; 
Java 中的数据类型分为 
1. 基本类型(原始数据类型) byte short int long float double char boolean 
基本类型的变量持有原始值。 
2. 符合数据类型(引用类型),引用类型持有引用值(即对某个对象的引用,而非对象本身)。

一般Java在内存分配时会涉及到以下区域: 
1. 寄存器:我们在程序中无法控制 
2. 栈:存放基本类型的数据和对象的引用但对象本身不存放在栈中,而是存放在堆中 
3. 堆:存放用new产生的数据 
4. 静态域:存放在对象中用static定义的静态成员 
5. 常量池:存放常量 
6. 非RAM存储:硬盘等永久存储空间 
其中主要是堆,栈的存储。

堆,栈

  1. 函数中定义的一些基本类型的数据变量对象的引用变量都在函数的栈内存中分配。 
    栈的优势是存取速度比堆要快,仅次于直接位于CPU 的寄存器,而且数据可以共享。但是存在栈中的数据大小与生存周期必须是确定的。 
    当在一段代码块定义一个变量时,Java就在栈中 为这个变量分配内存空间,当该变量退出该作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。
  2. 堆内存用来存放由new创建的对象和数组。 在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。 
    在堆中产生了一个数组或对象后,还可以 在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。 
    引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被释放。而数组和对象本身在堆中分配,即使程序 运行到使用 new 产生数组或者对象的语句所在的代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指向它的时候,才变为垃圾,不能在被使用,但仍 然占据内存空间不放,在随后的一个不确定的时间被垃圾回收器收走(释放掉)。

二 基本数据类型

这种类型是通过诸如 int a=7; 的形式来定义的,称为自动变量。这里自动变量是字面值。不是类的实例,即不是类的引用,这里并没有类的存在。a 是指向一个 int 类型的引用,指向 7 这个字面值。由于其大小确定生存期可知(这些定义在某个程序块中,程序块退出后,字段值就消失),因此存在中. 
由于栈的数据可以共享,因此 int a=3; int b=3; 这段代码,编译器首先处理 int a =3; ,先会在栈中创建一个变量为 a 的引用,然后查找有没有字面值为 3的地址,没有找到,就开辟一个存放 3 这个字面值的地址,然后将a 指向 3 的地址。接下来处理int b =3; 在创建完 b 这个引用变量后,由于栈中已经有 3 这个字面值,便将 b 指向 3 的地址。【定义变量,给变量赋值】

三 包装类数据

Java中的基本类型不是面向对象的,它们只是纯粹的数据,除了数值本身的信息之外,基本类型数据不带有其他信息或者可操作方法。这在实际使用中存在很多不足,为了解决这个不足,* 对每个基本类型都对应了一个引用的类型*,称为装箱基本类型。 

1,拆箱,装箱

装箱:根据数据创建对应的包装对象。

Integer i = new Integer (3);
Integer j = 4;//jdk1.5 之后可以通过这种方式自动装箱

拆箱:将包装类型转换为基本数据类型。

int  index2 = j.intValue();
int  index1 = i;//自动拆箱

JDK1.5 为Integer 增加了一个全新的方法:public static Integer valueOf(int i) 在自动装箱过程时,编译器调用的是static Integer valueOf(int i)这个方法 于是Integer a=3; ==> Integer a=Integer.valueOf(3);

此方法与new Integer(i)的不同处在于: 
方法一调用类方法返回一个表示 指定的 int 值的 Integer 实例。方法二产生一个新的Integer 对象。

2,缓冲机制

JDK API文档中对这个新的valueOf方法有明确的解释: 
如果不需要新的 Integer 实例,则通常应优先使用该方法,而不是构造方法 Integer(int),因为该方法有可能通过缓存经常请求的值而显著提高空间和时间性能 .

查看Integer的valueOf方法的:

    public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        //static final int low = -128;
        //当-128=<i<=127的时候,就直接在缓存中取出 i de  Integer 类型对象
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        //否则就在堆内存中创建
        return new Integer(i);
    }

看出对于范围 [-128,127] 的整数,valueOf 方法做了特殊处理。采用IntegerCache.cache[i + (-IntegerCache.low)]; 这个方法。

查看 IntegerCache 类的实现为:

    private static class IntegerCache {
        static final int low = -128; //最小值是固定的
        static final int high;
        static final Integer cache[];//cache 缓存是一个存放Integer类型的数组

        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) {
                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);
            }
            high = h;

            cache = new Integer[(high - low) + 1];  //初始化数组
            int j = low;
            //缓存区间数据
            for(int k = 0; k < cache.length; k++)
            //将-128~127包装成256个对象存入缓存
                cache[k] = new Integer(j++);
        }

        private IntegerCache() {}
    }

IntegerCache初始化后内存中就有Integer缓冲区cache[]了,-128~127区间的int值有其对应的的包装对象。这就是 valueOf 方法真正的优化方法,当-128=

public class ZhuangXaing {

    public static void main(String[] args) {
        Integer i= new Integer(12);
        Integer j=12;
        Integer k=Integer.valueOf(12);

        Integer l= new Integer(232);
        Integer m=232;
        Integer n=232;

        Double  q = 232.0;

        System.out.println("use ==.......");
        System.out.println(i==12);
        System.out.println(i==j);
        System.out.println(j==k);

        System.out.println(l==232);
        System.out.println(l==m);
        System.out.println(m==n);

        System.out.println("use equals.....");
        System.out.println(m.equals(n));
        System.out.println(m.equals(q));

    }

}

输出结果:

use ==.......
true
false
true
true
false
false
use equals.....
true
false

Integer i= new Integer(12); 是指明了在堆内存中创建对象; 
Integer j=12; 是自动装箱,调用valueOf 方法,返回return IntegerCache.cache[12 + 128], 得到的是Integer 缓冲池中的对象。Integer k=Integer.valueOf(12); 与Integer j=12; 本质上相同,指向缓冲池中同一对象。包装对象与数值比较,自动拆箱。 
而对于大于127 的数值,执行的都是return new Integer(i) 都在堆内存中,但是地址不同。

对于equals 方法比较的是数值大小:

public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

可以看出比较的 obj 如果是 Integer 的实例,则比较拆箱后数值的是否相等。否则返回false。

2,下面这段代码输出结果是什么:

public class Main {
    public static void main(String[] args) {

        Double i1 = 100.0;
        Double i2 = 100.0;
        Double i3 = 200.0;
        Double i4 = 200.0;

        System.out.println(i1==i2);
        System.out.println(i3==i4);
    }
//false
//false

因为Double类的valueOf方法会采用与Integer类的valueOf方法不同的实现。很简单:在某个范围内的整型数值的个数是有限的,而浮点数却不是。

其他的包装器: 
Boolean: (全部缓存) 
Byte: (全部缓存)

Character ( <=127 缓存) 
Short (-128~127 缓存) 
Long (-128~127 缓存)

Float (没有缓存) 
Doulbe (没有缓存)

3,下面这段代码输出结果是什么:

public class Main {
    public static void main(String[] args) {

        Boolean i1 = false;
        Boolean i2 = false;
        Boolean i3 = true;
        Boolean i4 = true;

        System.out.println(i1==i2);
        System.out.println(i3==i4);
    }
}

先看Boolean 类的源码 ,valueOf 方法的实现:

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

而其中的 TRUE 和FALSE又是什么呢?在Boolean中定义了2个静态成员属性:

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

    /**
     * The <code>Boolean</code> object corresponding to the primitive
     * value <code>false</code>.
     */
    public static final Boolean FALSE = new Boolean(false);

由此可知上面代码输出都为true .

时间: 02-12

Java中基本数据类型和包装类的相关文章

java中基本数据类型和包装类的区别

java中数据类型主要有两种: 1.基本的数据类型:long,int,byte,float,double,这些只是基本的数据类型,并不是对象 2.对象类型:Long,Integer,Byte,Float,Double以及其他所有的java对象 对于Interger和int,Integer是int的一个对象的封装,最简单版本的封装可以类似如下的封装 class Integer { private int i; public int intValue() { return i; } } 由于int是

Java基础(34):Java中基本数据类型的包装类(主要为了不同数据类型之间更方便的进行转换)

相信各位小伙伴们对基本数据类型都非常熟悉,例如 int.float.double.boolean.char 等.基本数据类型是不具备对象的特性的,比如基本类型不能调用方法.功能简单...,为了让基本数据类型也具备对象的特性, Java 为每个基本数据类型都提供了一个包装类,这样我们就可以像操作对象那样来操作基本数据类型. 基本类型和包装类之间的对应关系: 包装类主要提供了两大类方法: 1. 将本类型和其他基本类型进行转换的方法 2. 将字符串和本类型及包装类互相转换的方法 我们将在后面的小节逐步

JAVA中基本数据类型的包装类的常用方法

1.Integer.MIN_VALUE     保存int类型的最小值 2.Integer.,AX_VALUE     保存int类型的最大值 3.int  Integer.parseInt(String sInteger)   将字符串类型的整数转换为Int类型的数据 4.String Integer.toBinaryString(int value)  十进制转换为二进制,返回类型为String类型 5.String Integer.toHexString(int value)  十进制转换

Java中的基本类型和包装类

Java中基本数据类型与包装类型有   基本类型     包装器类型   boolean Boolean char Character int Integer byte Byte short Short long Long float Float double Double 存在基本类型对应包装类的原因: 基本数据类型存方在栈中,效率更高 new出来的对象存在于堆中(通过栈中的引用来使用这些对象),是一个对象,因此具有更多的诸如"转换"的方法 包装类型的意义 Java是一个面相对象的编

java中的数据类型和运算符的总结归类。

首先学习java肯定先要了解java的发展史,以及java的特点,常见的dos命令,jdk的安装,如何开发java程序等等一下概念行的东西,这里面我都不一一说了. 今天这一章主要想总结一下java中的数据类型和运算符2大方面. 再说数据类型之前先说一下标识符的命名规则: 总的命名规则:见名知意.如果有多个单词组成,首单词小写,其余单词的首字母大写(驼峰命名法).1.首字母只能是字母,下划线和$2.其余字母可以字母,下划线,$和数字3.不能使用预留关键字4.严格区分大小写(总体来说和c语音一样)

JAVA中的数据类型——西科软件实训中心

Java数据类型简介: Java是一种强类型的语言,数值类型主要分为基本数据类型和引用数据类型,其中基本的数据类型分为8种,具体细节点及一些注意点如下. java中的基本数据类型: 字符类型: 关键字:char  所占字节:2字节细节点:1.java中的字符类型采用Unicode编码,加之2字节,因此java中的数据类型可以直接存储一个汉字,例如:char sex = "男";注意点:1.声明字符类型时用的是单引号'',而不是双引号"". 布尔类型: 关键字:boo

细谈JAVA中的数据类型

Java数据类型简介: Java是一种强类型的语言,数值类型主要分为基本数据类型和引用数据类型,其中基本的数据类型分为8种,具体细节点及一些注意点如下. java中的基本数据类型: 字符类型: 关键字:char  所占字节:2字节细节点:1.java中的字符类型采用Unicode编码,加之2字节,因此java中的数据类型可以直接存储一个汉字,例如:char sex = '男';注意点:1.声明字符类型时用的是单引号' ',而不是双引号""; 2.其实在正常开发中,绝大多数汉字所占的字节

8中基本数据类型及其包装类

8中基本数据类型及其包装类 byte----------->Byte char------------>character short----------->short in--------------->Integer long------------>long float------------>Float double---------->Double boolean--------->Boolean

java中基本数据类型与对象引用类型的默认初始化值学习

import org.junit.Test; public class TestInit {     boolean boo;     char cha;     byte by;     short shor;     int in;     float flo;     long lon;     double dou;     String str;     @Test     public void aa() {         System.err.println("boolean:&