关于Integer的一系列问题

关于Integer的一系列问题

在学习设计模式的时候,学到享元模式的时候,介绍到了Integer(小声BB,看了半天也没发现有啥一样的地方,哈哈哈),但是发现了Integer中一个比较有趣的地方

完整代码:IntegerCache是一个静态内部类哟,像单例模式的静态内部类写法,但没有方法获取,无法让Integer类以外的类使用。

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) {
            try {
                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);
            } catch( NumberFormatException nfe) {
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);

        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {}
}

以前背八股文的时候,总会遇到一个问题,那就是

Integer s1 = Integer.valueOf(127);  
Integer s2 = Integer.valueOf(127);
System.out.println(s1 == s2);

以上代码输出为?答案是true,原因嘛,就是因为上述代码。

【简单说明,在设计Integer的时候,将用的最多最频繁的片段-128到127进行缓存,放在一个数组中,所以每次取这个范围内的Integer类型返回的都是同一个变量,内存地址也是相同的,所以用==进行判断返回为true

突然我看见一个非常陌生的代码片段

String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");

百度了一下,我发现这是Integer中获取的Integer缓存池最大值的方法。【默认范围是-128到127】

而上述的方法是用来获取integerCacheHighPropValue,根据代码上下文意思判断这个值是可以改变Integer初始化缓存-128到127范围的。

那么这个值如果改变了大小,以下代码会不会输出为true呢?

Integer val1 = Integer.valueOf(128);
Integer val2 = Integer.valueOf(128);
System.out.println(val1 == val2);

Talk is cheap. Show me the code.

为了方便测试,我在springboot项目中添加了启动选项

-Djava.lang.Integer.IntegerCache.high=300// 缓存最大值设置为300

接着,启动类中测试一下

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
        // -Djava.lang.Integer.IntegerCache.high=300
        Integer s1 = Integer.valueOf(127);
        Integer s2 = Integer.valueOf(127);
        System.out.println(s1 == s2);

        Integer val1 = Integer.valueOf(128);
        Integer val2 = Integer.valueOf(128);
        System.out.println(val1 == val2);
    }

}

结果是

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.7.RELEASE)

省略。。。。
2022-08-26 22:23:42.765  INFO 27604 --- [           main] com.ljq.demo.DemoApplication             : Started DemoApplication in 1.039 seconds (JVM running for 1.675)
true
true

哈哈哈~证实了我的想法。

结论

-Djava.lang.Integer.IntegerCache.high=300可以改变Integer默认缓存的范围,参考代码

if (integerCacheHighPropValue != null) {
     try {
         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);
     } catch( NumberFormatException nfe) {
         // If the property cannot be parsed into an int, ignore it.
     }
 }
 high = h;

 cache = new Integer[(high - low) + 1];
 int j = low;
 for(int k = 0; k < cache.length; k++)
     cache[k] = new Integer(j++);

最后还有几个面试题~

问:两个new Integer 128相等吗?

答:不。因为Integer缓存池默认是-128-127;【问题出处在最后,但出处中这个问题的答案有问题】

问:可以修改Integer缓存池范围吗?如何修改?

答:可以。使用-Djava.lang.Integer.IntegerCache.high=300设置Integer缓存池大小

问:Integer缓存机制使用了哪种设计模式?

答:亨元模式;

问:Integer是如何获取你设置的缓存池大小?

答:sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high")

问:sun.misc.VM.getSavedPropertySystem.getProperty有啥区别?

答:唯一的区别是,System.getProperty只能获取非内部的配置信息;例如java.lang.Integer.IntegerCache.highsun.zip.disableMemoryMappingsun.java.launcher.diagsun.cds.enableSharedLookupCache等不能获取,这些只能使用sun.misc.VM.getSavedProperty获取

问题来自于 https://www.cnblogs.com/hujinshui/p/11350435.html 虽然第一个问题他写的是-127到128,但还是感谢解惑~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值