前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java中的享元设计模式,涨姿势了!

Java中的享元设计模式,涨姿势了!

作者头像
Java技术栈
发布2019-11-18 13:53:15
3270
发布2019-11-18 13:53:15
举报
文章被收录于专栏:Java技术栈Java技术栈
首先来看一段代码:
代码语言:javascript
复制
public class ShareTest {
  public static void main(String[] args) {
    Integer a = 127;
    Integer b = 127;
    System.out.println(a==b);
    Integer c = 128;
    Integer d = 128;
    System.out.println(c==d);
  }
}

运行结果为:true false

为什么会出现这种情况呢?我们来从源代码中分析一下,首先Integer a = 127这行代码调用的是Integer中的valueOf方法,我们来看看这个方法的源码:

代码语言:javascript
复制
public static Integer valueOf(int i) {
  assert IntegerCache.high >= 127;
  if (i >= IntegerCache.low && i <= IntegerCache.high)
    return IntegerCache.cache[i + (-IntegerCache.low)];
  return new Integer(i);
}

其中IntegerCache就是Integer中的一个内部类,看下这篇:IntegerCache的妙用和陷阱,从这段代码中我们可以看出,当我的参数i的范围在low和high之间时,会直接返回这个内部类中的一个数组中对应的值,否则会创建一个新的对象。

那么我们再来看你看这个数组是怎么创建的:

代码语言:javascript
复制


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) {
      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++)
      cache[k] = new Integer(j++);
  }

  private IntegerCache() {}
}

由这段代码我们可以知道,这个内部类在初始化的时候创建了一个数组,并且这个数组的长度为 (high-low+1),然后遍历循环,创建了从-128到127这256个Integer对象,并将它们放入到这个数组中。

另外,推荐大家关注微信公众号:Java技术栈,在后台回复:设计模式,可以获取我整理的 N 篇最新设计模式教程,都是干货。

所以当我们在调用valueOf的时候,如果值得范围是在128到127之间,那么是不会创建新的对象的,但是如果超过了这个范围,那么就会创建姓的对象。这就是之前代码运行结果的原因。

到了这里,享元模式的核心思想已经渐渐清晰了,其实就是将一些常用的对象缓存起来,在使用的时候直接拿过来使用,不必创建新的对象,这个省去了创建对象时消耗的资源,也省去了GC在回收这些垃对象时消耗的资源。

在我们日常开发中,享元模式还是比较常见的,最典型的就是池技术,例如服务器的线程池,JDBC的连接池,这些都是享元模式的很好的体现,当然,常量池也是享元模式思想。

作者:Mazin

https://my.oschina.net/u/3441184/blog/886337

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java技术栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档