首页 > 编程语言 >Java基础之基本数据类型封装类的缓存

Java基础之基本数据类型封装类的缓存

时间:2023-06-23 13:44:06浏览次数:49  
标签:缓存 Java i5 数据类型 i4 System 127 println out

巨人的肩膀:https://blog.csdn.net/hnjcxy/article/details/123787209
1、Java中基本数据类型byte、short、char、int、long、float、double、boolean有对应的封装类型:Byte、Short、Character、Integer、long、Float、Double,Boolean其中Byte、Short、Character、Integer、Long、Boolean都实现了常量池缓存。Byte、Short、Character、Integer、Long通过静态内部Cache类来实现一定范围(下面列出缓存范围)内的数据缓存,而Boolean通过两个静态常量TRUE、FALSE来实现数据缓存。

  • Byte类缓存范围:[-128,127] 共256个值。
  • Short类缓存范围:[-128,127] 共256个值。
  • Character类缓存范围:[0,127] 共128个值。
  • Integer类默认缓存范围:[-128,127] 共256个值,可以通过修改VM参数-XX:AutoBoxCacheMax=200 即可修改缓存上限到200
  • Long类缓存范围:[-128,127] 共256个值。
  • Boolean类就缓存两个值:true、false。
2、装箱和拆箱过程:
装箱:调用封装类 valueOf(x) 方法;
拆箱:调用封装类的 xxValue() 方法。

3、测试
测试前说明:
==对于基本数据类型和对象的比较含义是不同的。对于基本数据类型:“==” 比较的是基本数据类型的数值;对于对象:“==” 比较的是对象在内存中的内存地址。
byte、short、char类型计算后会自动转成整型类型int。

(1)Byte

    static void testByte(){
        System.out.println("Byte类型:");
        Byte i1 = 127;
        Byte i2 = 127;
        Byte i3 = 0;
        Byte i4 = new Byte("127");
        Byte i5 = new Byte("127");
        Byte i6 = new Byte("0");
 
        System.out.println("i1=i2 " + (i1 == i2));  //true 因为数值在[-128,127]的范围内,使用常量池缓存中的127
 
        System.out.println("i1=i4 " + (i1 == i4)); //false 因为i1指向常量池Byte对象127,i4指向堆中Byte对象127
 
        System.out.println("i4=i5 " + (i4 == i5)); //false 因为i4和i5是堆中两个对象
 
        //因为 i5+i6 做算数运算+时,会自动拆箱再做加法,即拆箱后的基本数据类型byte做加法运算,
        //计算结果是整型的127,所以最终是基本数据类型的值作比较;(byte、short、char类型计算后会自动转成整型类型int)
        System.out.println("127=i5+i6 " + (127 == i5 + i6)); //true
        System.out.println("byte计算后,转换类型为:"+ myGetType(i5 + i6));  // int
 
        //因为 i2+i3 做算数运算+时,会自动拆箱再做加法,即拆箱后的基本数据类型byte做加法运算,计算结果是整型的127;
        // i1与基本数据类型127比较的时候也会自动拆箱,所以最终是基本数据类型的值作比较
        System.out.println("i1=i2+i3 " + (i1 == i2 + i3)); //true
 
        //因为 i2+i3 做算数运算+时,会自动拆箱再做加法,即拆箱后的基本数据类型byte做加法运算,计算结果是整型的127;
        // i4与基本数据类型127比较的时候也会自动拆箱,所以最终是基本数据类型的值作比较
        System.out.println("i4=i5+i6 " + (i4 == i5 + i6)); //true
 
        /* Byte类中有缓存静态内部类ByteCache;缓存范围:-128~127,共256(cache.length)个值
        private static class ByteCache {
            private ByteCache(){}
            static final Byte cache[] = new Byte[-(-128) + 127 + 1];
            static {
                for(int i = 0; i < cache.length; i++)
                    cache[i] = new Byte((byte)(i - 128));
            }
        }
         */
    }

(2)Short

    static void testShort(){
        System.out.println("Short类型:");
        Short i1 = 127;
        Short i2 = 127;
        Short i3 = 0;
        Short i4 = new Short("127");
        Short i5 = new Short("127");
        Short i6 = new Short("0");
        Short i1New = 128;
        Short i2New = 128;
 
        System.out.println("i1=i2 " + (i1 == i2));  //true 因为数值在[-128,127]的范围内,使用常量池缓存中的127
 
        System.out.println("i1New=i2New " + (i1New == i2New));  //false 超过缓存范围,创建新对象了
 
        System.out.println("i1=i4 " + (i1 == i4)); //false 因为i1指向常量池对象127,i4指向堆中对象127
 
        System.out.println("i4=i5 " + (i4 == i5)); //false 因为i4和i5是堆中两个对象
 
        //因为 i5+i6 做算数运算+时,会自动拆箱再做加法,即拆箱后的基本数据类型short做加法运算,
        //计算结果是整型的127,所以最终是基本数据类型的值作比较;(byte、short、char类型计算后会自动转成整型类型int)
        System.out.println("127=i5+i6 " + (127 == i5 + i6)); //true
        System.out.println("short计算后,转换类型为:"+ myGetType(i5 + i6));  // int
 
        //因为 i2+i3 做算数运算+时,会自动拆箱再做加法,即拆箱后的基本数据类型short做加法运算,计算结果是整型的127;
        // i1与基本数据类型127比较的时候也会自动拆箱,所以最终是基本数据类型的值作比较
        System.out.println("i1=i2+i3 " + (i1 == i2 + i3)); //true
 
        //因为 i2+i3 做算数运算+时,会自动拆箱再做加法,即拆箱后的基本数据类型short做加法运算,计算结果是整型的127;
        // i4与基本数据类型127比较的时候也会自动拆箱,所以最终是基本数据类型的值作比较
        System.out.println("i4=i5+i6 " + (i4 == i5 + i6)); //true
 
        /* Short类中有缓存静态内部类ShortCache;缓存范围:-128~127,共256(cache.length)个值
        private static class ShortCache {
            private ShortCache(){}
            static final Short cache[] = new Short[-(-128) + 127 + 1];
            static {
                for(int i = 0; i < cache.length; i++)
                    cache[i] = new Short((short)(i - 128));
            }
        }
         */
    }

(3)Character

    static void testChar(){
        System.out.println("Character类型:");
        Character i1New72 = 72;
        Character i1 = 40; //表示字符'('
        Character i2 = 40;
        Character i3 = 32;
        Character i4 = new Character('(');//字符'('的十进制码点值是40
        Character i4New72 = new Character('H');//字符'H'的十进制码点值是72
        Character i5 = new Character('(');
        Character i6 = new Character(' '); //空格的十进制码点值是32
        Character i1New = 128;
        Character i2New = 128;
        Character i1New1 = 127;
        Character i2New2 = 127;
 
        System.out.println("i1=i2 " + (i1 == i2));  //true 因为数值在[0,127]的范围内,使用常量池缓存中的40
 
        System.out.println("i1New=i2New " + (i1New == i2New));  //false 超过缓存范围,创建新对象了
 
        System.out.println("i1New1=i2New2 " + (i1New1 == i2New2));  //true 没有超过缓存范围,使用常量池缓存中的值
 
        System.out.println("i1=i4 " + (i1 == i4)); //false 因为i1指向常量池Character对象40,i4指向堆中Character对象40
 
        System.out.println("i4=i5 " + (i4 == i5)); //false 因为i4和i5是堆中两个对象
 
        //因为 i5+i6 做算数运算+时,会自动拆箱再做加法,即拆箱后的基本数据类型char做加法运算,
        //计算结果是整型的72,所以最终是基本数据类型的值作比较;(byte、short、char类型计算后会自动转成整型类型int)
        System.out.println("72=i5+i6 " + (72 == i5 + i6) +" 因为:i5+i6= " + (i5 + i6)); //true
        System.out.println("char计算后,转换类型为:"+ myGetType(i5 + i6));  // int
 
        //因为 i2+i3 做算数运算+时,会自动拆箱再做加法,即拆箱后的基本数据类型char做加法运算,计算结果是整型的72;
        // i1New72与基本数据类型72比较的时候也会自动拆箱,所以最终是基本数据类型的值作比较
        System.out.println("i1New72=i2+i3 " + (i1New72 == i1 + i3)); //true
        System.out.println("i4New72=i5+i6 " + (i4New72 == i5 + i6)); //true
 
        //因为 i2+i3 做算数运算+时,会自动拆箱再做加法,即拆箱后的基本数据类型char做加法运算,计算结果是整型的72;
        // i4New72与基本数据类型72比较的时候也会自动拆箱,所以最终是基本数据类型的值作比较
        System.out.println("i4=i5+i6 " + (i4New72 == i5 + i6) +" 因为:i5+i6= " + (i5 + i6)); //true
 
        Character c = '(';
        System.out.println("字符‘(’的码点值:" + (int)c); //40
 
        /* Caracter类中有缓存静态内部类CharacterCache;缓存范围:0~127,共128(cache.length)个值
        private static class CharacterCache {
            private CharacterCache(){}
 
            static final Character cache[] = new Character[127 + 1];
 
            static {
                for (int i = 0; i < cache.length; i++)
                    cache[i] = new Character((char)i);
            }
        }
         */
    }

(4)Integer

    static void testInt(){
        System.out.println("Boolean类型:");
        Integer i1 = 127;
        Integer i2 = 127;
        Integer i3 = 0;
        Integer i4 = new Integer(127);
        Integer i5 = new Integer(127);
        Integer i6 = new Integer(0);
        Integer i1New = 128;
        Integer i2New = 128;
 
        System.out.println("i1=i2 " + (i1 == i2));  //true 因为数值在[-128,127]的范围内,使用常量池缓存中的127
 
        System.out.println("i1New=i2New " + (i1New == i2New));  //false 超过缓存范围,创建新对象了
 
        System.out.println("i1=i4 " + (i1 == i4)); //false 因为i1指向常量池对象127,i4指向堆中对象127
 
        System.out.println("i4=i5 " + (i4 == i5)); //false 因为i4和i5是堆中两个对象
 
        //因为 i5+i6 做算数运算+时,会自动拆箱再做加法,所以结果是拆箱后的基本数据类型int,所以最终是基本数据类型的值作比较
        System.out.println("127=i5+i6 " + (127 == i5 + i6)); //true
 
        //因为 i2+i3 做算数运算+时,会自动拆箱再做加法,所以结果是拆箱后的基本数据类型int;i1与基本数据类型比较的时候也会自动拆箱
        System.out.println("i1=i2+i3 " + (i1 == i2 + i3)); //true
 
        //因为 i5+i6 做算数运算+时,会自动拆箱再做加法,所以结果是拆箱后的基本数据类型int;
        //i4与i5+i6的基本数据类型int结果比较时,i4也会自动拆箱,所以最终是基本数据类型的值作比较
        System.out.println("i4=i5+i6 " + (i4 == i5 + i6)); //true
 
        /* Integer类中有缓存静态内部类IntegerCache;默认缓存范围:-128~127,共256(cache.length)个值;
            但是可通过 java.lang.Integer.IntegerCache.high 修改高位值,例如:设置vm参数 -XX:AutoBoxCacheMax=200 即
            可修改缓存上限为200
        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() {}
        }
         */
    }

Idea2021通过配置VM options修改Integer缓存上限,具体配置参考:

Idea2021.3.2 设置项目运行参数配置_hnjcxy的博客-CSDN博客Idea2021.3.2 设置运行参数配置:Program arguments 、 Environment variables 和 VM options。1、点击Run -> Edit Configurations2、在打开的窗口可以设置 Program arguments 和 Environment variables 参数,如果需要设置VM参数,请看第三步设置VM参数。设置Program arguments参数时,多个参数中间用空格分开,如:"22" "33" "44"。.imghttps://blog.csdn.net/hnjcxy/article/details/123791208

(5)Long

    static void testLong(){
        System.out.println("Long类型:");
        Long i1 = 127L;
        Long i2 = 127L;
        Long i3 = 0L;
        Long i4 = new Long(127L);
        Long i5 = new Long(127L);
        Long i6 = new Long(0);
        Long i1New = 128L;
        Long i2New = 128L;
 
        System.out.println("i1=i2 " + (i1 == i2));  //true 因为数值在[-128,127]的范围内,使用常量池缓存中的127L
 
        System.out.println("i1New=i2New " + (i1New == i2New));  //false 超过缓存范围,创建新对象了
 
        System.out.println("i1=i4 " + (i1 == i4)); //false 因为i1指向常量池对象127L,i4指向堆中对象127L
 
        System.out.println("i4=i5 " + (i4 == i5)); //false 因为i4和i5是堆中两个对象
 
        //因为 i5+i6 做算数运算+时,会自动拆箱再做加法,所以结果是拆箱后的基本数据类型long,所以最终是基本数据类型的值作比较
        System.out.println("127L=i5+i6 " + (127L == i5 + i6)); //true
 
        //因为 i2+i3 做算数运算+时,会自动拆箱再做加法,所以结果是拆箱后的基本数据类型long;i1与基本数据类型比较的时候也会自动拆箱
        System.out.println("i1=i2+i3 " + (i1 == i2 + i3)); //true
 
        //因为 i5+i6 做算数运算+时,会自动拆箱再做加法,所以结果是拆箱后的基本数据类型long;
        //i4与i5+i6的基本数据类型long结果比较时,i4也会自动拆箱,所以最终是基本数据类型的值作比较
        System.out.println("i4=i5+i6 " + (i4 == i5 + i6)); //true
 
        /* long类中有缓存静态内部类ByteCache;缓存范围:-128~127,共256(cache.length)个值
        private static class LongCache {
            private LongCache(){}
            static final Long cache[] = new Long[-(-128) + 127 + 1];
            static {
                for(int i = 0; i < cache.length; i++)
                    cache[i] = new Long(i - 128);
            }
        }
         */
 
    }

(6)Boolean

    static void testBool(){
        System.out.println("Boolean类型:");
        Boolean i1 = true;
        Boolean i2 = true;
        Boolean i4 = new Boolean("true");
        Boolean i5 = new Boolean("true");
 
        System.out.println("i1=i2 " + (i1 == i2));  //true 因为i1、i2使用常量池缓存中的true
 
        System.out.println("i1=i4 " + (i1 == i4)); //false 因为i1指向常量池对象true,i4指向堆中对象true,所以两个对象地址不同
 
        System.out.println("i4=i5 " + (i4 == i5)); //false 因为i4和i5是堆中两个对象,比较的是两个对象地址
 
        //因为 i5 与常量true比较时,会自动拆箱为基本数据类型boolean,所以最终比较的是值,不是对象地址
        System.out.println("true=i5+i6 " + (true == i5)); //true
 
    }

(7)Double 和 Float 没有缓存

    static void testDouble(){
        System.out.println("Double类型:");
        Double i1 = 127.0;
        Double i2 = 127.0;
        Double i3 = 0.0;
        Double i4 = new Double(127.0);
        Double i5 = new Double(127.0);
        Double i6 = new Double(0);
 
        System.out.println("i1=i2 " + (i1 == i2));  //false 没有缓存,是两个不同的Double类型对象
 
        //因为 i2+i3 做算术运算+时,会自动拆箱再做加法,所以结果是拆箱后的基本类型double数值127.0,i1与基本数据类型比较时,
        // 也需要拆箱成基本数据类型,最后比较两个基本数据类型127.0的值是否相等
        System.out.println("i1=i2+i3 " + (i1 == i2 + i3)); //true
 
        System.out.println("i1=i4 " + (i1 == i4)); //false 没有缓存,是两个不同的Double类型对象
 
        System.out.println("i4=i5 " + (i4 == i5)); //false 没有缓存,是两个不同的Double类型对象
 
        //因为 i5+i6 做算数运算+时,会自动拆箱再做加法,所以结果是基本数据类型double;最后比较两个基本数据类型127.0的值是否相等
        System.out.println("127.0=i5+i6 " + (127.0 == i5 + i6)); //true
        System.out.println("Double计算后,类型为:"+ myGetType(i5 + i6));  // int
 
        //因为 i5+i6 做算数运算+时,会自动拆箱再做加法,所以结果是基本数据类型double;i4与i5+i6的基本数据类型结果比较时,
        // i4也会自动拆箱成基本数据类型double,最后是比较基本数据类型的值,而不是比较封装类对象地址
        System.out.println("i4=i5+i6 " + (i4 == i5 + i6)); //true
 
 
    }
测试中用到的判断基本数据类型的方法:
//判断类型
    public static String myGetType(Object o) {
        String type = o.getClass().getSimpleName();
        if ("Integer".equals(type)) {
            return String.valueOf(Integer.TYPE);
        } else if ("Long".equals(type)) {
            return String.valueOf(Long.TYPE);
        } else if ("Float".equals(type)) {
            return String.valueOf(Float.TYPE);
        } else if ("Double".equals(type)) {
            return String.valueOf(Double.TYPE);
        } else if ("Short".equals(type)) {
            return String.valueOf(Short.TYPE);
        } else if ("Byte".equals(type)) {
            return String.valueOf(Byte.TYPE);
        } else if ("Character".equals(type)) {
            return String.valueOf(Character.TYPE);
        } else if ("Boolean".equals(type)) {
            return String.valueOf(Boolean.TYPE);
        }
        return "非基本数据类型!";
    }

标签:缓存,Java,i5,数据类型,i4,System,127,println,out
From: https://www.cnblogs.com/javaxubo/p/17499060.html

相关文章

  • java.util.concurrent.RejectedExecutionException 问题
    java.util.concurrent.RejectedExecutionException问题 http://qingfeng825.iteye.com/blog/1670511 http://blog.sina.com.cn/s/blog_6145ed81010143l8.html http://yaozhiqiang109.iteye.com/blog/1137579......
  • mysql的数据类型以及mysql中的int11是什么意思
    今天抽时间来讲一下mysql里的知识点,之前有不少人问过我,mysql中的int(11),这个11到底是啥意思?是11位的意思吗?你是否也想过这个问题,是否也有这个疑问?ok,今天就展开来讲一下,用通俗易懂的大白话来给你彻底搞明白一、跟你扯点二进制的小东西要讲清楚这个问题,我先来给大家科普一点计算......
  • Java打怪升级路线
    第一关:JavaSE阶段1、计算机基础2、java入门学习3、java基础语法4、流程控制和方法5、数组6、面向对象编程7、异常8、常用类9、集合框架10、IO11、多线程12、GUI编程13、网络编程14、注解与反射15、JUC编程16、JVM探究17、23种设计模式18、数据结构与算法19、正......
  • Java 泛型
    泛型GenricsJava泛型是在jdk5引入的新特性。它指定了接收参数的类型,避免了调用者乱传参,保留了代码的通用性和独特性。泛型类和泛型方法一般使用大写字母声明泛型,例如<T>类型擦除Typeerasure思考:能否插入一个字符串元素到一个整型数组中?答案:通过反射是可以的,原理就是类......
  • Java学习-集合篇
    集合什么是集合?有什么用?数组其实就是一个集合。集合实际上就是一个容器。可以来容纳其他类型的数据。集合为什么说在开发中使用的较多?集合是一个容器,是一个载体,可以依次容纳多个对象。在实际的开发中,假设连接数据库,数据库当中有10条记录,那么假设把这10条记录查询出来,在java程......
  • java线程的五种状态
    五种状态开始状态(new)就绪状态(runnable)运行状态(running)阻塞状态(blocked)结束状态(dead)状态变化1、线程刚创建时,是new状态2、线程调用了start()方法后,进入runnable状态,此时并未真正执行,需要和其他线程竞争cpu资源3、当该线程竞争到了cpu资源,进入running状态4、线程因为某种......
  • 前端缓存【http缓存 | 浏览器缓存】
    一、前端缓存分类【http缓存|浏览器缓存】1、http缓存分类:强缓存 协商缓存   都是服务端设置HTTPHeader来实现的(1)强缓存不需要发送请求到服务端,直接读取浏览器本地缓存//在Chrome的Network中显示的HTTP状态码是200在Chrome中,强缓存又分为DiskCac......
  • Java中 = 和 += 的区别
    问题shorts1=1;s1=s1+1;有什么错?shorts1=1;s1+=1;有错吗?讨论1)+:在编译器将右边的表达式结果计算出来后,和左边的变量类型比较精度,如果左边的变量精度低于右边的结果的精度,编译器会显式的报错,告诉程序员去强制转型。(所以s1=s1+1出错)最后将表达式的结果复......
  • Java基础:自动装箱和自动拆箱
    感谢,原文链接:https://www.cnblogs.com/dolphin0520/p/3780005.htmlJava的自动包装类型首先基本数据类型:4类8种基本数据类型对应包装器类byte(1字节)Byteshort(2字节)Shortint(4字节)Integerlong(8字节)Longfloat(4字节)Floatdouble(8字节)Doublechar(2字......
  • golang 给对象的基础数据类型的指针类型的属性赋值
    概要有时我们可能碰到定义成下面这样的结构体,结构体里某些属性是基础数据类型,更确切的说,是基础数据类型的指针类型。typeStudentstruct{ namestring`json:"name"` age*int`json:"age"`//age是整型指针}不可行的写法此时该如何对这种成员属性进行赋值呢,下面......