精华内容
下载资源
问答
  • Integer中有个静态内部类 IntegerCache ,里面有个cache[],也就是Integer常量池 大小为一个字节(-128-127). 源码送上(jdk1.8.0_101) private static class IntegerCache { static final int low = -128; ...

    首先一道小题送上!

    Integer中有个静态内部类 IntegerCache ,里面有个cache[],也就是Integer常量池  大小为一个字节(-128-127).

    源码送上(jdk1.8.0_101)

    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() {}
        }
    

    A 选项    体现了自动拆箱的特性。  所以两者相等

    B 选项   .valueOf()方法中  在一个字节之内的数都会返回一个常量池中的对象   所以相等

    c 选项    因为有new的关系所以会开辟一块新的内存存放59,两者地址不同 所以不等

    D 选项   两者地址不一样应该是错的  ,但是正相反  Integer 引用类型 int 是基本类型   integer会自动拆箱,调用intValue的

                  方法,返回int类型  两个基本类型相比 值相等 必然相等。

    展开全文
  • -128~127,只有这个范围的数字可以用到常量池。,有字符串常量池,可以把这理解为整数常量池Integer aa1 = 126; Integer bb1 = 126; System.out.println(aa1 == bb1); 这时是true 但超过这个范围,就要...

     

     

    -128~127,只有这个范围的数字可以用到常量池。,有字符串常量池,可以把这理解为整数常量池。

     

    Integer aa1 = 126;
    Integer bb1 = 126;
    System.out.println(aa1 == bb1);

     

    这时是true

     

    但超过这个范围,就要新创建对象,

    Integer aa1 = 128;
    Integer bb1 = 128;
    System.out.println(aa1 == bb1);

    这时是 false

    展开全文
  • Integer常量池

    2020-08-31 23:50:50
    Integer常量池 Integer包装类有默认缓存池,范围是【 -128~127】 。 其他基本数据类型的包装类都有这个缓存池,包括:Byte,Short,Long。 public static Integer valueOf(int i) { // 大小为256的缓存池,超出范围就...

    Integer常量池

    Integer包装类有默认缓存池,范围是【 -128~127】 。
    其他基本数据类型的包装类都有这个缓存池,包括:Byte,Short,Long。

    public static Integer valueOf(int i) {
    	// 大小为256的缓存池,超出范围就新建对象,否则取出池中常量
            return  i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];
        }
    
        /**
         * A cache of instances used by {@link Integer#valueOf(int)} and auto-boxing
         */
        private static final Integer[] SMALL_VALUES = new Integer[256];
    
        static {
            for (int i = -128; i < 128; i++) {
            // 放入对象,方便存取加上偏移
                SMALL_VALUES[i + 128] = new Integer(i);
            }
        }
    

    实例:

     		int a = 10;
            Integer b = 10;
            Integer bb = 10;
            Integer c = new Integer(10);
            Integer cc = new Integer(10);
            Integer d = Integer.valueOf("127");
            Integer e = Integer.valueOf(127);
            Integer ee = Integer.valueOf(127);
            Integer f = Integer.valueOf(128);
            Integer ff = Integer.valueOf(128);
    
            System.out.println( a==b);// true:int和Integer会自动转型比较int数值
            System.out.println(b==bb);// true:虽然是引用,但是都是从Integer默认缓存池取出【-128~127】
            System.out.println(b==c);// false:栈中常量和堆中对象
            System.out.println(c==cc);// false:不同对象地址不同
            System.out.println(b.equals(c));// true:值相同
            System.out.println(d==e);// true:Integer.valueOf取出缓存池的对象
            System.out.println(e == ee);// true:默认缓存池
            System.out.println(f==ff);// false:常量池范围是-128~127,128超出常量池范围
    
    展开全文
  • 1.Integer常量池 看下面一段代码: package cn.qlq.test; public class ArrayTest { public static void main(String[] args) { Integer i1 = new Integer(1); Integer i2 = new Integer(1); ...

    1.Integer的常量池

    看下面一段代码:

    package cn.qlq.test;
    
    public class ArrayTest {
        public static void main(String[] args) {
            Integer i1 = new Integer(1);
            Integer i2 = new Integer(1);
            System.out.println(i1.hashCode());
            System.out.println(i2.hashCode());
            System.out.println(i1 == i2);
            System.out.println(i1.equals(i2));
    
            System.out.println("-------------------");
    
            Integer i3 = 1;
            Integer i4 = 1;
            System.out.println(i3.hashCode());
            System.out.println(i4.hashCode());
            System.out.println(i3 == i4);
            System.out.println(i3.equals(i4));
    
        }
    
    }

     

     

     1
    1
    false
    true
    -------------------
    1
    1
    true
    true

     

    基本知识:我们知道,如果两个引用指向同一个对象,用==表示它们是相等的。如果两个引用指向不同的对象,用==表示它们是不相等的,即使它们的内容相同。

    解释:Integer i1 = new Integer(1)的时候是在Java堆中创建一个Integer对象,i1指向堆中的对象,i1与常量池没关系,所以i1==i2为false。

      Integer i3=1;的时候是从常量池中查找值为1的常量,i3指向该常量;Integer i4=1的时候会直接指向该常量,所以 i3 == i4为true。

     

    这就是它有趣的地方了。如果你看去看 Integer.Java 类,你会发现有一个内部私有类,IntegerCache.java,它缓存了从-128到127之间的所有的整数对象。

     

     

     

    所以事情就成了,所有的小整数在内部缓存,然后当我们声明类似——

            Integer bInteger=127;

     

     

    它实际在内部的操作是:

            Integer bInteger=Integer.valueOf(127);

     

     

     

    现在,如果我们去看valueOf()方法,我们可以看到:

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

    如果值的范围在-128到127之间,它就从高速缓存返回实例。

    所以…下面这两个指向同一个对象:

            Integer aInteger=127;
            Integer bInteger=127;

    我们可以得到true。


    现在你可能会问,为什么这里需要缓存?

      合乎逻辑的理由是,在此范围内的“小”整数使用率比大整数要高,因此,使用相同的底层对象是有价值的,可以减少潜在的内存占用。

      然而,通过反射API你会误用此功能。

     

     

     

    现在对代码进行反编译和反汇编查看:

    package zd.dms.test;
    
    public class ArrayTest {
    
        public static void main(String[] args) {
            Integer i1 = 25;
            Integer i2 = new Integer(26);
        }
    }

     

    反编译:

    package zd.dms.test;
    
    public class ArrayTest
    {
      public static void main(String[] paramArrayOfString)
      {
        Integer localInteger1 = Integer.valueOf(25);
        Integer localInteger2 = new Integer(26);
      }
    }

     

    反汇编:

    C:\Users\Administrator\Desktop>javap -c -v ArrayTest.class
    Classfile /C:/Users/Administrator/Desktop/ArrayTest.class
      Last modified 2018-9-3; size 384 bytes
      MD5 checksum 6535da703ea8fa15da765de7bb03300b
      Compiled from "ArrayTest.java"
    public class zd.dms.test.ArrayTest
      SourceFile: "ArrayTest.java"
      minor version: 0
      major version: 51
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #6.#15         //  java/lang/Object."<init>":()V
       #2 = Methodref          #3.#16         //  java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       #3 = Class              #17            //  java/lang/Integer
       #4 = Methodref          #3.#18         //  java/lang/Integer."<init>":(I)V
       #5 = Class              #19            //  zd/dms/test/ArrayTest
       #6 = Class              #20            //  java/lang/Object
       #7 = Utf8               <init>
       #8 = Utf8               ()V
       #9 = Utf8               Code
      #10 = Utf8               LineNumberTable
      #11 = Utf8               main
      #12 = Utf8               ([Ljava/lang/String;)V
      #13 = Utf8               SourceFile
      #14 = Utf8               ArrayTest.java
      #15 = NameAndType        #7:#8          //  "<init>":()V
      #16 = NameAndType        #21:#22        //  valueOf:(I)Ljava/lang/Integer;
      #17 = Utf8               java/lang/Integer
      #18 = NameAndType        #7:#23         //  "<init>":(I)V
      #19 = Utf8               zd/dms/test/ArrayTest
      #20 = Utf8               java/lang/Object
      #21 = Utf8               valueOf
      #22 = Utf8               (I)Ljava/lang/Integer;
      #23 = Utf8               (I)V
    {
      public zd.dms.test.ArrayTest();
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: return
          LineNumberTable:
            line 3: 0
    
      public static void main(java.lang.String[]);
        flags: ACC_PUBLIC, ACC_STATIC
        Code:
          stack=3, locals=3, args_size=1
             0: bipush        25
             2: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
             5: astore_1
             6: new           #3                  // class java/lang/Integer
             9: dup
            10: bipush        26
            12: invokespecial #4                  // Method java/lang/Integer."<init>":(I)V
            15: astore_2
            16: return
          LineNumberTable:
            line 6: 0
            line 7: 6
            line 8: 16
    }

     

    bipush 25     将25推至栈顶

    invokestatic  调用Integer的静态方法valueOf(int)方法

    astore_1          将栈顶引用型数值存入第二个本地变量

    new   调用new Integer(int)

     dup   复制栈顶数值(数值不能是long或double类型的)并将复制值压入栈顶

    bipush 26     将26推至栈顶

    invokespecial  调用Integer的初始化方法(init)

    astore_2         将栈顶引用型数值存入第三个本地变量

    return   返回,类型是void

     

    补充:

      aload_0                                                            //将this引用推送至栈顶,即压入栈。

     

    总结:Integer i = value;如果i是在-128到127之间,不会去堆中创建对象,而是直接返回IntegerCache中的值;如果值不在上面范围内则会从堆中创建对象。= 走的是valueOf()方法,valueOf(int)会走缓存。

      Integer i2 = new Integer(xxxx);不管参数的value是多少都会从堆中创建对象,与IntegerCache没关系。

      

     

     

    2.String常量池问题:

    package cn.qlq.test;
    
    public class ArrayTest {
        public static void main(String[] args) {
            String s1 = new String("1");
            String s2 = new String("1");
            System.out.println(s1.hashCode());// 49
            System.out.println(s2.hashCode());// 49
            System.out.println(s1 == s2);// false
            System.out.println(s1.equals(s2));// true
    
            System.out.println("-------------------");
    
            String s3 = "1";
            String s4 = "1";
            System.out.println(s3 == s4);// true
            System.out.println(s3.equals(s4));// true
            System.out.println(s3.hashCode());// 49
            System.out.println(s4.hashCode());// 49
    
        }
    
    }

     

      String的hashCode不是返回地址,是对其值进行遍历运算。与地址没关系,只对值计算,所以所有的hashCode一样。

      String s1 = new String("1"); 是在堆中创建一个String对象,并检查常量池中是否有字面量为"1"的常量,没有的话在常量区创建"1"并将堆中的对象指向该常量,有的话堆中的对象直接指向"1";

      String s2 = new String("1"); 又在堆中创建一个String对象,并将s2指向该对象,其字面量"1"在前面已经创建,所以不会再创建常量区中创建字符串;

      

      String s3 = "1";   检查常量池中有没有字面量为"1"的字符串,如果没有则创建并将s3指向该常量;有的话直接指向该该常量;

      String s4 = "1"  的时候常量池已经有1,所以不会再创建对象,也就是s3与s4指向同一个对象。

     

    所以我们可以用下面图解解释,String s = new String("xxx")在检查常量池的时候会涉及到堆中创建对象;String s = "x"直接检查常量池,不会涉及堆。

     

     

    如下图解:

     

     

    一道经典的面试题:new String("abc")创建几个对象?

      简单的回答是一个或者两个,如果是常量区有值为"abc"的值,则只在堆中创建一个对象;如果常量区没有则会在常量区创建"abc",此处的常量区是方法区的运行时常量池(也称为动态常量区)。

     

     

       我们需要明白只要是new都会在堆中创建对象。直接String s = "xxx"不会涉及堆,只在常量区检查是否有该常量。

     

    展开全文
  • 我们知道,Integer默认的常量池大小是-128~127,如图所示: 只要我们使用的是这个范围内的Integer包装类型的值,那么就一直会从缓存池中获取。 这可真是一次存入,终生获取呀! 我们考虑下这个情况哈,比如一个热点...
  • Java中 Integer包装类常量池 在本文中,我们将研究一下Integer常量池和其常量池的用途? IntegerInteger类作为最常用的包装类,相信大家都不陌生,那么,你了解自动装箱和手动创建实例对象间的区别么?请看下一...
  • Java Integer 常量池

    万次阅读 热门讨论 2013-12-17 15:14:28
    在本文中,我们将研究一下Integer类和Integer常量池以及Integer常量池的用途? Integer类  Integer 类在对象中包装了一个基本类型 int 的值。Integer 类型的对象包含一个 int 类型的字段。  此外,该类提供了多...
  • Integer常量池  当我们创建两个Integer对象的时候,有可能会出现它们指向的内存地址一致的情况,下面就来详细的讲一下什么时候会出现这个情况。首先来看一下程序实例: public static void main(String[] args)...
  • Integer 类 ...上面代码会调用Integer.valueOf()方法,该方法会缓存-128-127之间的对象,如果i 处于该范围,则直接返回缓存对象。 Integer.valueOf 方法: public static Integer valueOf( ...
  • 1.Integer存在缓存吗?i == j会返回什么 举例一:Integer i = 10; Integer j = new Integer(10) 举例二:Integer a = 128; Integer b = 128; 举例三:Integer j= 129; int k = j; 解:i在编译的时候实际上是...
  • Java Integer常量池

    2017-02-16 10:26:00
    public class IntegerExample { public static void main(String[] javalatte) { Integer i = 10; Integer j = new Integer(10); Integer k = 130; Integer p = new In...
  • //128不在Integer常量池范围内,所以会重新new一个对象,输出false 四.jdk1.5之后会自动进行包装类和基本数据类型直接按类型的转换,也就是自动拆箱和装箱。 将一个基本数据类型变为包装类型的过程叫自动装箱...
  • 一个Java question,求输出结果 public class IntegerTest { public static void main(String[] args) { objPoolTest(); } public static void objPoolTest() { Integer i1 = 40; Int...
  • Integer n1 =4; Integer n2 =4; if(n1==n2){ System.out.println("n1==n2"); }else{ System.out.println("n1!=n2"); } //结果是n1==n2 Integer a1 =450; Integer a2 =450; if(a1==a2){ System.out.printl...
  • * 注意:Integer的数据直接赋值,如果在-128到127之间,会直接从缓冲里获取数据 */ public class IntegerDemo { public static void main(String[] args) { Integer i1 = new Integer(127); Integer i2 = ...
  • java Integer常量池

    2019-10-06 14:20:01
    Integer b= 127 时,这两个变量使用的地址是一样的,当数字不在0到127的范围内是,在常量池中不存在,就会新建一个对象,地址也是不一样的 转载于:https://www.cnblogs.com/zhangscth/p/3446084.html...
  • 细节问题2:Integer什么时候会使用常量池里的值什么时候会new一个? package classandobject; public class Integer_Int { public static void main(String[]args){ // 1)基本类型和包装类型 int a = 100;//...
  • // newInteger与int11: Integer i11 = new Integer(120);会自动拆箱(即:堆里的内容 拿到栈里面)变成 i11=120; 就比较值了 而不是地址了 System.out.println("---newInteger与int11---"+(i11==i2)); //...
  • Java架构师交流群:793825326 java版本:jdk1.8 IDE:idea 18 int是值类型,Integer是引用类型,Integer是int的包装类。...Integer integer1=new Integer(i); Integer integer2=new Integer(i); Syst...
  • Integer和int 常量池问题

    千次阅读 2019-11-24 17:24:31
    Byte, Short, Integer, Long, Character, Boolean, Float, Double, 除Float和Double以外, 其它六种都有常量池,,只在大于等于-128并且小于等于127时使用常量池 1. int i=128; integer i2=128,相等 自动拆装箱 int和...
  • 对于字符串String的学习一直是迷迷糊糊,但这块知识却也是重点,要...在自己看了深入理解Java虚拟机这本书后,结合多篇博客,才感觉稍微入门,用这篇博客总结记录一下自己理解下的字符串常量池。 一、常量池 link ...
  • Integer a=140; Integer b=140; Integer a1=1; Integer b1=1; int c=140;... //注意Integer常量池范围 System.out.println(a==b); //注意,编译时看左运行时看右,实际调用的的Integer的equals方...
  • 字符串常量池、class常量池和运行时常量池

    万次阅读 多人点赞 2017-06-12 20:09:36
    在java的内存分配中,经常听到很多关于常量池的描述,我开始看的时候也是看的很模糊,网上五花八门的说法简直太多了,最后查阅各种资料,终于算是差不多理清了,很多网上说法都有问题,笔者尝试着...
  • 常量池与运行时常量池

    千次阅读 2018-07-22 14:35:56
    * 转载自 [java虚拟机:运行时常量池](https://www.cnblogs.com/xiaotian15/p/6971353.html) ...Class文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量池(Constant Pool Table),用于...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,568
精华内容 9,027
关键字:

integer常量池范围