为什么Java要废掉包装类的构造器?


最近学到了发短文的技巧. 尽量少食多餐. 这篇也很短, 主要聊聊Integer.IntegerCache.

1听说, 新款Java里, 基础值int,boolean,long对应的Integer,Boolean,Long等都不让用构造器了?

那么, 是真是假呢?

翻开源码,检查Integer的构造器. 画风是这样的.

@Deprecated(since = "9", forRemoval = true)
public Integer(int value) {
  this.value = value;
}

@Deprecated(since = "9", forRemoval = true)
public Integer(String s) throws NumberFormatException {
  this.value = parseInt(s, 10);
}

看注释, 发现是这么写的:

Deprecated It is rarely appropriate to use this constructor

It is rarely appropriate to use this constructor. The static factory valueOf(int) is generally a better choice, as it is likely to yield significantly better space and time performance.

歌词大意: 用的人少, Integer.valueOf 时间空间性能更好.

得,一句话完了. 那这谣言顶多少是用词不准, 还真有这么个事儿.

2那么,Integer.valueOf 怎么就时空性能好了?

为什么Java要废掉包装类的构造器?

因为这里用的是一个Integer[]缓存.

3如何反射取Integer类的私有静态内部类IntegerCache属性.

先岔开一下,今天手贱想画一把IntegerCache的缓存.结果发现, 没法 反射拿到他的信息.  我还没有对private的类做过反射操作.

记录下找到的方法:Class.getDeclaredClasses()

//获取私有静态内部类
Class integerCache = Arrays.stream(Integer.class.getDeclaredClasses())
.filter(x -> Modifier.isPrivate(x.getModifiers()))
.findFirst().get();
//反射 我还是用joor来操作.
org.joor.Reflect.onClass(integerCache).get("cache");

不过虽然成功了,发现这东西没什么好画的,作罢.

4这个IntegerCache是做什么用的呢?

其实很简单, 就是对一些int值做一些缓存. 他们转成包装类时候, 不会再重新生成对象了.直接从缓存取.他里面就是个Integer[]

5缓存边界是多少?

[-128,127+]

上界可以自由定义,但是不得低于127.

6缓存生效时间

只要敢加载IntegerCache类, 就会自动把上限和下限之间的数字全都生成一遍.

7上界怎么自由定义?

上界high可以通过-XX:AutoBoxCacheMax=N调整为127+

然而也不是无限大.因为初始化流程是刷新high-low个,所以如果这个数字过大.high-low会溢出.😁

还记得我们上一篇的图吗? 一样的毛病.

为什么Java要废掉包装类的构造器?

8这个缓存我记得以前没啊, 啥时候加的?

查了下历史, 出现在Java5

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);
 }
}

早期版本十分简单, 就是固定缓存了几个.后面版本加上的自定义上界功能.

Java8里面还出现了奇怪的 -1 这个修改.. 看来为了这个自定义上界功能,没少出bug啊也是.

h = Math.min(i, Integer.MAX_VALUE - (-low) -1);

9Integer Cache什么时候起作用.

Integer.valueOf时候起作用.如果是new Integer(int)的话,这里没效果. 

所以, 为什么官方要废掉构造器, 其实很明显了.


题外话, 构造器在某些时候真的是错的.. 比如下面这个式子…

new Boolean(true) == new Boolean(true)

原文始发于微信公众号(K字的研究):为什么Java要废掉包装类的构造器?

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/24845.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!