Java 为什么要有包装类? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
Acceml
V2EX    程序员

Java 为什么要有包装类?

  •  
  •   Acceml
    Acceml 2018-09-04 13:50:34 +08:00 3823 次点击
    这是一个创建于 2605 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我谈谈我的理解,欢迎指正!

    为什么这么设计

    java 中 new 一个对象,会把这个对象存储在堆里面,所有的类都是 object 的子类,通过 stack 指向堆。 1.java 中的对象很多都是朝生夕死的,所以一直放在堆中不是很高效; 2.Java 是一个面相对象的编程语言,基本类型并不具有对象的性质,为了让基本类型也具有对象的特征,就出现了包装类型(如我们在使用集合类型 Collection 时就一定要使用包装类型而非基本类型),它相当于将基本类型“包装起来”,使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。

    不同

    1. 声明方式不同:基本类型不使用 new 关键字,而包装类型需要使用 new 关键字来在堆中分配存储空间;

    2. 存储方式及位置不同:基本类型是直接将变量值存储在栈中,而包装类型是将对象放在堆中,然后通过引用来使用;

    3. 初始值不同:基本类型的初始值如 int 为 0,boolean 为 false,而包装类型的初始值为 null ;

    4. 使用方式不同:基本类型直接赋值直接使用就好,而包装类型在集合如 Collection、Map 时会使用到。

    取舍

    这样做也不是没有代价,装箱和拆箱的性能差距,在大数据和大并发的环境中会被体现出来。 以答主所做的广告系统为例,广告系统中大量存在如下类型的数据: 广告 Id: long 广告价格: double app 的 Id : int ...

    由于 java 提供了默认 box unbox 的操作,例如更新某个广告当前的价格就需要数据结构 Map<Long, Double>,这个时候就自动从 long -> Long , double -> Double. 更新操作还不太明显,但是查询广告价格几乎是每一个请求都会有的,这个时候 box, unbox 就会大大的降低性能。 对此,我们团队线上的代码没有使用 java 的原生 jdk 中的 Map、Set、List 等结构,而是使用了 Eclipse Collections。Eclipse Collections 起源于 2004 年在高盛公司内部开发的一个名为 Caramel 的集合框架。这个框架就可以使得 Map<long,Object>这样的结构,不存在 box 和 unbox。 在我们的广告下发引擎中,上线后大概缩短了 5ms 的 latency.我们团队属于比较尝鲜那种,新的技术够比较敢用,现在线上即将升级 jdk10.有兴趣的小伙伴可以参考官网文档: http://www.eclipse.org/collections/cn/index.html

    下面列出官网文档所给的和原生 jdk 比较的数据.

    image.png

    image.png

    image.png


    Leetcode 名企之路

    8 条回复    2018-09-04 22:35:54 +08:00
    jiqing
        1
    jiqing  
       2018-09-04 13:54:07 +08:00 via Android   1
    文章是挺好的,但是末尾的广告就很硬了。
    简而言之就是,基本数据类型不能当成一个对象使用。包装类可以把基本数据类型转换成一个对象。对象能干的包装类都能干。
    Acceml
        2
    Acceml  
    OP
       2018-09-04 13:56:36 +08:00
    @jiqing 我们线上使用的情况这个对 GC 和延时还是有蛮大影响的,换掉之后大概能缩短 5ms。主要原因是系统太大,涉及到的开发人员太多,大家也不注意。
    feverzsj
        3
    feverzsj  
       2018-09-04 14:00:56 +08:00
    因为 java 很嗦
    BBCCBB
        4
    BBCCBB  
       2018-09-04 14:09:16 +08:00
    据我所知,还有 fastutil 库也提供支持原生类型的集合, 但这个库太大了, 10 多 M
    lhx2008
        5
    lhx2008  
       2018-09-04 14:13:41 +08:00 via Android
    如果是大量数据,用 stream 等流式操作库更好,可以控制拆装箱。底层是数组
    hhsuan
        6
    hhsuan  
       2018-09-04 14:14:38 +08:00
    我觉得这个问题可以反过来问:java 为什么要支持原生类型?
    lovedebug
        7
    lovedebug  
       2018-09-04 14:16:16 +08:00
    因为 JVM 中一个对象还是很占内存的,需要存储额外的描述信息。所以额外设计基本类型
    Acceml
        8
    Acceml  
    OP
       2018-09-04 22:35:54 +08:00
    @lhx2008 stream 并不能呢控制 box unbox 吧。

    @BBCCBB 这个库不算大。我们已经在线上使用了,千万级收入的系统,目前效果还不错。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5356 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 07:56 PVG 15:56 LAX 00:56 JFK 03:56
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86