`

java学习笔记:装箱和拆箱,包装器和缓冲池

    博客分类:
  • java
阅读更多

jdk1.5以后
Integer举例
Integer a = 3;              这是自动装箱
int     i = new Integer(2); 这是自动拆箱
就是基本类型和其对应的包装类型在需要的时候可以互相转换,具体过程由编译器完成
比如自动装箱:
Integer a=3;
其实编译器调用的是static Integer valueOf(int i)这个方法
查阅JDK知道,
valueOf(int i)返回一个表示指定的 int 值的 Integer 对象
那么就变成这样: Integer a=3;   =>    Integer a=Integer.valueOf(3);

 

对应的  int intValue()  返回该 Integer对象的int值,是拆箱

 

我们再来看Integer缓存, 
下面是IntegerCache类的源码,我加上了注释,便于讨论

private static class IntegerCache   //定义类名   
{     
    static final int high;     
    static final Integer cache[];   //cache缓存是一个存放Integer类型的数组   
  
    static  //初始化   
    {     
        final int low = -128;       //最小值是固定的   
        int h = 127;                //最大值暂时是127   
        if (integerCacheHighPropValue != null) //这段if代码不用深究,是一些判断,我看得眼花啊   
        {     
            int i = Long.decode(integerCacheHighPropValue).intValue();     
            i     = Math.max(i, 127);     
            h     = Math.min(i, Integer.MAX_VALUE - -low);     
        }     
        high = h;  //此时high就是127   
  
        cache = new Integer[(high - low) + 1];  //有256个元素   
        int j = low;                            //j的初始值是-128   
        for(int k = 0; k < cache.length; k++)   //缓存区间数据      
            cache[k] = new Integer(j++);        //将-128~127包装成256个对象存入缓存   
    }     
    private IntegerCache(){}  //构造方法,不需要构造什么   
}  

  

再来看valueOf方法

 

public static Integer valueOf(int i)    
{     
    if(i >= -128 && i <= IntegerCache.high)   
    {   
        //如果i在-128~127之间,就直接在缓存中取出i的Integer类型对象   
        return IntegerCache.cache[i + 128];     
    }       
    else   
    {   
        return new Integer(i);  //否则就在堆内存中创建   
    }       
}   

 

 

valueOf方法会自动调用IntegerCache这个类,
IntegerCache初始化后内存中就有Integer缓冲区cache[]了,
-128~127区间的int值有其对应的的包装对象
java使用该机制是为了达到最小化数据输入和输出的目的,这是一种优化措施,提高效率
其他的包装器:
Boolean: (全部缓存)
Byte:    (全部缓存)

 

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

 

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

补充下我对Integer缓冲池对理解:

(这个观点是我在网上看到的一些资料加上自己看源码后的一些推断,但没有在哪本书上看到过这种说法,最近打算看think in java)
缓冲池是java对系统的优化,它是一种管理内存的机制,是一种数据结构,它可以管理多个缓冲区,IntegerCache就是一个缓冲区,cache[]数组中保存的是指向Integer类型对象的指针,虽然Integer缓冲对象是new出来的,但是是由缓冲池管理,欢迎一起讨论.
然后回答一个网友的提问,问题比较典型,我贴到上面来,

先说String str = "aaa";
"aaa"本身就是一个字符串对象,它在编译时就被定义在了数据区,在运行时直接创建到常量池,或者说数据区,而str是当程序运行到这句代码时系统在内存的栈区分配的一个指针变量,指向了常量池中的"aaa"对象,
如果是String str = new String("aaa"); 在编译时,"aaa"对象被创建到数据区,在运行时执行到new String()时,程序动态的开辟一块内存空间,
并将数据区中的"aaa"对象复制一份到堆中,并返回一个引用给str所在栈中,此时这一条语句创建了1个新的String对象。加上原来在数据区中的对象一共2个对象,不知道我说的对不对,请大家指教..

还有一网友问 "Doulbe没有缓存,能说为啥莫?"

Doulbe    (没有缓存)

我也是在网上看到的,我查了下java文档源码
    public static Double valueOf(double d) {
        return new Double(d);
    }

代码中确实没有用到缓冲
对比Integer的valueOf方法,是不一样的,所以才有这个结论的吧!

====================================================

 

知道了这些原理

我们再来看一些网上关于java的有趣问题,就能知道答案了

下面我们对一网友帖子中的问题的做解答,我当时也是看到这个帖子才baidu学到这些内容的

http://xiaoyu1985ban.iteye.com/blog/1384191

主题:java迷题:等于,还是不等于?

代码片段1

public static void main(final String[] args) {  

    Integer a = new Integer(100);  

    Integer b = 100;  

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

} 

解答:

结果输出 false

因为new Integer(100)是指明了再堆内存中创建对象

Integer b = 100; 这句是自动装箱,

得到的是Integer缓冲池中的对象,是这句代码return IntegerCache.cache[100 + 128]

明显ab的地址是不一样的,不是同一个对象

 

代码片段2

public static void main(final String[] args) {  

    Integer a = 100;  

    Integer b = 100;  

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

} 

解答:

结果输出 true

ab指向了同一个对象,都是IntegerCache.cache[100 + 128]

 

代码片段3

public static void main(final String[] args) {  

    Integer a = 156;  

    Integer b = 156;  

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

} 

解答:

结果输出 false

由于156大于128,它的包装对象不在缓冲池中,而是执行 return new Integer(156);

new2,都在堆内存中,但地址不一样

 

代码片段4

public static void main(final String[] args) {  

    Integer a = Integer.valueOf(100);  

    Integer b = 100;  

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

}

解答:

结果输出 true

我们上面说过了,Integer b = 100 就相当于Integer b=Integer.valueOf(100)

所以ab指向缓冲池中的同一对象

 

 

 

9
4
分享到:
评论
16 楼 yzz9i 2012-02-07  
xouou_53320 写道
yzz9i 写道
Float     (没有缓存)
Doulbe    (没有缓存) 能说为啥莫

这2句话,我也是在网上看到的,我查了下java文档源码
    public static Double valueOf(double d) {
        return new Double(d);
    }
它确实没有用到缓冲池
对比Integer的valueOf方法,是不一样的,所以才有这个结论的吧!
你认为呢?

我不是很清楚,
15 楼 xouou_53320 2012-02-02  
723766146 写道
if (integerCacheHighPropValue != null) //这段if代码不用深究,是一些判断,我看得眼花啊    
        {      
            int i = Long.decode(integerCacheHighPropValue).intValue();      
            i     = Math.max(i, 127);      
            h     = Math.min(i, Integer.MAX_VALUE - -low);      
        }

这个判断的作用是,cache中的最大值是可以配置的,integerCacheHighPropValue 是胚子的值

哦,多谢
14 楼 723766146 2012-02-02  
if (integerCacheHighPropValue != null) //这段if代码不用深究,是一些判断,我看得眼花啊    
        {      
            int i = Long.decode(integerCacheHighPropValue).intValue();      
            i     = Math.max(i, 127);      
            h     = Math.min(i, Integer.MAX_VALUE - -low);      
        }

这个判断的作用是,cache中的最大值是可以配置的,integerCacheHighPropValue 是胚子的值
13 楼 m635674608 2012-02-02  
xouou_53320 写道
11楼的哥么你也觉得这样吗? 这些只是我的以前在网上看的资料加上自己的一些推测,
而且源码中似乎也是这样的,但我
没有具体看到哪本书上有这个说法,最近打算看看 think in java ,


是啊。我也觉得是这样的啊。我感觉你技术应该不错啊。。
我也比较喜欢研究底层的技术。。源码什么的。。。
12 楼 xouou_53320 2012-02-01  
11楼的哥么你也觉得这样吗? 这些只是我的以前在网上看的资料加上自己的一些推测,
而且源码中似乎也是这样的,但我
没有具体看到哪本书上有这个说法,最近打算看看 think in java ,
11 楼 m635674608 2012-02-01  
xouou_53320 写道
燈小嗨 写道
xouou_53320 写道
燈小嗨 写道
请问“Integer缓冲池中的对象” 是放在堆中吗?

我觉得是的,因为是new出来的对象,你认为呢?

我觉得有可能啊,就是说不同的引用共享了堆内存。那会不会有可能是和String str = "aaa"中的str一样不放在堆中呢?

先来补充下我对Integer缓冲池对理解:
缓冲池是java对系统的优化,它是一种管理内存的机制,是一种数据结构,它可以管理多个缓冲区,IntegerCache就是一个缓冲区,cache[]数组中保存的是指向Integer类型对象的指针,虽然Integer缓冲对象是new出来的,但是是由缓冲池管理,我没有书本,这个理解方式只是看源代码自己想的,可能不对,欢迎一起讨论.
然后说String str = "aaa";
"aaa"本身就是一个字符串对象,它在编译时就被定义在了数据区,在运行时直接创建到常量池,或者说数据区,而str是当程序运行到这句代码时系统在内存的栈区分配的一个指针变量,指向了常量池中的"aaa"对象,
如果是String str = new String("aaa"); 在编译时,"aaa"对象被创建到数据区,在运行时执行到new String()时,程序动态的开辟一块内存空间,
并将数据区中的"aaa"对象复制一份放到堆中,并返回一个引用复制到str所在栈中,此时这一条语句创建了1个新的String对象。加上原来在数据区中的对象一共2个对象,不知道我说的对不对,仅供讨论..

xouou_53320 写道
燈小嗨 写道
xouou_53320 写道
燈小嗨 写道
请问“Integer缓冲池中的对象” 是放在堆中吗?

我觉得是的,因为是new出来的对象,你认为呢?

我觉得有可能啊,就是说不同的引用共享了堆内存。那会不会有可能是和String str = "aaa"中的str一样不放在堆中呢?

先来补充下我对Integer缓冲池对理解:
缓冲池是java对系统的优化,它是一种管理内存的机制,是一种数据结构,它可以管理多个缓冲区,IntegerCache就是一个缓冲区,cache[]数组中保存的是指向Integer类型对象的指针,虽然Integer缓冲对象是new出来的,但是是由缓冲池管理,我没有书本,这个理解方式只是看源代码自己想的,可能不对,欢迎一起讨论.
然后说String str = "aaa";
"aaa"本身就是一个字符串对象,它在编译时就被定义在了数据区,在运行时直接创建到常量池,或者说数据区,而str是当程序运行到这句代码时系统在内存的栈区分配的一个指针变量,指向了常量池中的"aaa"对象,
如果是String str = new String("aaa"); 在编译时,"aaa"对象被创建到数据区,在运行时执行到new String()时,程序动态的开辟一块内存空间,
并将数据区中的"aaa"对象复制一份放到堆中,并返回一个引用复制到str所在栈中,此时这一条语句创建了1个新的String对象。加上原来在数据区中的对象一共2个对象,不知道我说的对不对,仅供讨论..

不错、、这位童鞋理解的很到位
10 楼 xouou_53320 2012-02-01  
燈小嗨 写道
xouou_53320 写道
燈小嗨 写道
请问“Integer缓冲池中的对象” 是放在堆中吗?

我觉得是的,因为是new出来的对象,你认为呢?

我觉得有可能啊,就是说不同的引用共享了堆内存。那会不会有可能是和String str = "aaa"中的str一样不放在堆中呢?

先来补充下我对Integer缓冲池对理解:
缓冲池是java对系统的优化,它是一种管理内存的机制,是一种数据结构,它可以管理多个缓冲区,IntegerCache就是一个缓冲区,cache[]数组中保存的是指向Integer类型对象的指针,虽然Integer缓冲对象是new出来的,但是是由缓冲池管理,我没有书本,这个理解方式只是看源代码自己想的,可能不对,欢迎一起讨论.
然后说String str = "aaa";
"aaa"本身就是一个字符串对象,它在编译时就被定义在了数据区,在运行时直接创建到常量池,或者说数据区,而str是当程序运行到这句代码时系统在内存的栈区分配的一个指针变量,指向了常量池中的"aaa"对象,
如果是String str = new String("aaa"); 在编译时,"aaa"对象被创建到数据区,在运行时执行到new String()时,程序动态的开辟一块内存空间,
并将数据区中的"aaa"对象复制一份放到堆中,并返回一个引用复制到str所在栈中,此时这一条语句创建了1个新的String对象。加上原来在数据区中的对象一共2个对象,不知道我说的对不对,仅供讨论..
9 楼 xouou_53320 2012-02-01  
据说缓冲池是由系统管理的,它可以包含多个类型的缓冲区,比如Integer的缓冲IntegerCache, 或者Byte类型的缓冲   
public static Byte valueOf(byte b) {
        final int offset = 128;
        return ByteCache.cache[(int)b + offset];
    }
8 楼 xouou_53320 2012-02-01  
yzz9i 写道
Float     (没有缓存)
Doulbe    (没有缓存) 能说为啥莫

这2句话,我也是在网上看到的,我查了下java文档源码
    public static Double valueOf(double d) {
        return new Double(d);
    }
它确实没有用到缓冲池
对比Integer的valueOf方法,是不一样的,所以才有这个结论的吧!
你认为呢?
7 楼 yzz9i 2012-02-01  
Float     (没有缓存)
Doulbe    (没有缓存) 能说为啥莫
6 楼 燈小嗨 2012-02-01  
xouou_53320 写道
燈小嗨 写道
请问“Integer缓冲池中的对象” 是放在堆中吗?

我觉得是的,因为是new出来的对象,你认为呢?

我觉得有可能啊,就是说不同的引用共享了堆内存。那会不会有可能是和String str = "aaa"中的str一样不放在堆中呢?
5 楼 xouou_53320 2012-01-31  
燈小嗨 写道
请问“Integer缓冲池中的对象” 是放在堆中吗?

我觉得是的,因为是new出来的对象,你认为呢?
4 楼 燈小嗨 2012-01-31  
请问“Integer缓冲池中的对象” 是放在堆中吗?
3 楼 xouou_53320 2012-01-31  
1楼的朋友你是jdk是什么版本啊?

2楼的朋友可以编译的 ,我的是jdk7
2 楼 jancyjin 2012-01-31  
兄弟在jdk1.5下自己试试再发表意见行不...
raitt79 写道
  Integer a = 156;  
    Integer b = 156;
胡扯这样写jdk编译都不会通过需要转换成int类型的

1 楼 raitt79 2012-01-31  
  Integer a = 156;  
    Integer b = 156;
胡扯这样写jdk编译都不会通过需要转换成int类型的

相关推荐

    java基础笔记

    - 字符串池:Java为优化字符串操作提供,常量池的一部分。 - 字符串创建的区别: - `String s = "abc"`:直接引用字符串池中的对象。 - `String s = new String("abc")`:创建新的String对象。 - 字符串连接...

    cyc学习笔记.pdf

    在Java中,包装类型具有缓冲池机制,以提高性能。 1. **Integer缓存池**:在-128到127的整数值范围内,Integer对象会复用已存在的实例,避免重复创建。这是因为Integer类中有一个私有的静态内部类IntegerCache,它...

    个人笔记--Java_API

    - **作用**:装箱和拆箱。 - **构造方法**:`new Integer(10);` - **常用方法**: - `parseInt(String s)`:字符串转整数。 - `toString(int i)`:整数转字符串。 **3.3 Math类** - **常用方法**: - `abs...

    传智播客视频JavaSE学习笔记

    以上是根据传智播客视频JavaSE学习笔记总结的关键知识点,覆盖了Java基础环境配置、字符串操作、多线程编程、集合框架、输入输出流、网络编程、反射机制、正则表达式等多个方面,希望对Java初学者和进阶者有所帮助。

    Matlab环境下决策分类树的构建、优化与应用

    内容概要:本文详细介绍了如何利用Matlab构建、优化和应用决策分类树。首先,讲解了数据准备阶段,将数据与程序分离,确保灵活性。接着,通过具体实例展示了如何使用Matlab内置函数如fitctree快速构建决策树模型,并通过可视化工具直观呈现决策树结构。针对可能出现的过拟合问题,提出了基于成本复杂度的剪枝方法,以提高模型的泛化能力。此外,还分享了一些实用技巧,如处理连续特征、保存模型、并行计算等,帮助用户更好地理解和应用决策树。 适合人群:具有一定编程基础的数据分析师、机器学习爱好者及科研工作者。 使用场景及目标:适用于需要进行数据分类任务的场景,特别是当需要解释性强的模型时。主要目标是教会读者如何在Matlab环境中高效地构建和优化决策分类树,从而应用于实际项目中。 其他说明:文中不仅提供了完整的代码示例,还强调了代码模块化的重要性,便于后续维护和扩展。同时,对于初学者来说,建议从简单的鸢尾花数据集开始练习,逐步掌握决策树的各项技能。

    《营销调研》第7章-探索性调研数据采集.pptx

    《营销调研》第7章-探索性调研数据采集.pptx

    Assignment1_search_final(1).ipynb

    Assignment1_search_final(1).ipynb

    美团外卖优惠券小程序 美团优惠券微信小程序 自带流量主模式 带教程.zip

    美团优惠券小程序带举牌小人带菜谱+流量主模式,挺多外卖小程序的,但是都没有搭建教程 搭建: 1、下载源码,去微信公众平台注册自己的账号 2、解压到桌面 3、打开微信开发者工具添加小程序-把解压的源码添加进去-appid改成自己小程序的 4、在pages/index/index.js文件搜流量主广告改成自己的广告ID 5、到微信公众平台登陆自己的小程序-开发管理-开发设置-服务器域名修改成

    《计算机录入技术》第十八章-常用外文输入法.pptx

    《计算机录入技术》第十八章-常用外文输入法.pptx

    基于Andorid的跨屏拖动应用设计.zip

    基于Andorid的跨屏拖动应用设计实现源码,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。

    《网站建设与维护》项目4-在线购物商城用户管理功能.pptx

    《网站建设与维护》项目4-在线购物商城用户管理功能.pptx

    区块链_房屋转租系统_去中心化存储_数据防篡改_智能合约_S_1744435730.zip

    区块链_房屋转租系统_去中心化存储_数据防篡改_智能合约_S_1744435730

    《计算机应用基础实训指导》实训五-Word-2010的文字编辑操作.pptx

    《计算机应用基础实训指导》实训五-Word-2010的文字编辑操作.pptx

    《移动通信(第4版)》第5章-组网技术.ppt

    《移动通信(第4版)》第5章-组网技术.ppt

    ABB机器人基础.pdf

    ABB机器人基础.pdf

    《综合布线施工技术》第9章-综合布线实训指导.ppt

    《综合布线施工技术》第9章-综合布线实训指导.ppt

    最新修复版万能镜像系统源码-最终版站群利器持续更新升级

    很不错的一套站群系统源码,后台配置采集节点,输入目标站地址即可全自动智能转换自动全站采集!支持 https、支持 POST 获取、支持搜索、支持 cookie、支持代理、支持破解防盗链、支持破解防采集 全自动分析,内外链接自动转换、图片地址、css、js,自动分析 CSS 内的图片使得页面风格不丢失: 广告标签,方便在规则里直接替换广告代码 支持自定义标签,标签可自定义内容、自由截取、内容正则截取。可以放在模板里,也可以在规则里替换 支持自定义模板,可使用标签 diy 个性模板,真正做到内容上移花接木 调试模式,可观察采集性能,便于发现和解决各种错误 多条采集规则一键切换,支持导入导出 内置强大替换和过滤功能,标签过滤、站内外过滤、字符串替换、等等 IP 屏蔽功能,屏蔽想要屏蔽 IP 地址让它无法访问 ****高级功能*****· url 过滤功能,可过滤屏蔽不采集指定链接· 伪原创,近义词替换有利于 seo· 伪静态,url 伪静态化,有利于 seo· 自动缓存自动更新,可设置缓存时间达到自动更新,css 缓存· 支持演示有阿三源码简繁体互转· 代理 IP、伪造 IP、随机 IP、伪造 user-agent、伪造 referer 来路、自定义 cookie,以便应对防采集措施· url 地址加密转换,个性化 url,让你的 url 地址与众不同· 关键词内链功能· 还有更多功能等你发现…… 程序使用非常简单,仅需在后台输入一个域名即可建站,不限子域名,站群利器,无授权,无绑定限制,使用后台功能可对页面进行自定义修改,在程序后台开启生 成功能,只要访问页面就会生成一个本地文件。当用户再次访问的时候就直接访问网站本地的页面,所以目标站点无法访问了也没关系,我们的站点依然可以访问, 支持伪静态、伪原创、生成静态文件、自定义替换、广告管理、友情链接管理、自动下载 CSS 内的图。

    《Approaching(Almost)any machine learning problem》中文版第11章

    【自然语言处理】文本分类方法综述:从基础模型到深度学习的情感分析系统设计

    基于Andorid的下拉浏览应用设计.zip

    基于Andorid的下拉浏览应用设计实现源码,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。

    P2插电式混合动力系统Simulink模型:基于逻辑门限值控制策略的混动汽车仿真

    内容概要:本文详细介绍了一个原创的P2插电式混合动力系统Simulink模型,该模型基于逻辑门限值控制策略,涵盖了多个关键模块如工况输入、驾驶员模型、发动机模型、电机模型、制动能量回收模型、转矩分配模型、运行模式切换模型、档位切换模型以及纵向动力学模型。模型支持多种标准工况(WLTC、UDDS、EUDC、NEDC)和自定义工况,并展示了丰富的仿真结果,包括发动机和电机转矩变化、工作模式切换、档位变化、电池SOC变化、燃油消耗量、速度跟随和最大爬坡度等。此外,文章还深入探讨了逻辑门限值控制策略的具体实现及其效果,提供了详细的代码示例和技术细节。 适合人群:汽车工程专业学生、研究人员、混动汽车开发者及爱好者。 使用场景及目标:①用于教学和科研,帮助理解和掌握P2混动系统的原理和控制策略;②作为开发工具,辅助设计和优化混动汽车控制系统;③提供仿真平台,评估不同工况下的混动系统性能。 其他说明:文中不仅介绍了模型的整体架构和各模块的功能,还分享了许多实用的调试技巧和优化方法,使读者能够更好地理解和应用该模型。

Global site tag (gtag.js) - Google Analytics