【JVM系列】字符串常量池

字符串常量池

概念

  • 字符串常量池是一个大小固定的HashTable,默认长度是1009。
  • java6存放在永久代,java7和java8存放到java堆中。

常见面试题

  1. 用双引号定义的字符串是直接存储到常量池,用new String创建的是存放在堆中。
        String s1 = "123";//存储到字符串常量池
        String s2 = new String("123");
        System.out.println(s1 == s2);  //false
        System.out.println(s1.equals(s2)); // true
  1. 常量的拼接存放到常量池,s4也是直接从常量池中获取,是同一个对象。
 		String s3 = "a" + "b" + "c"; // 常量的拼接会存储到常量池
        String s4 = "abc";
        System.out.println(s3 == s4);
  1. 变量拼接常量,等价于StringBuilder的append,所以s3的对象存放在堆中。
 		String s1 = "abc";
        String s2 = "def";
        String s3 = s1 + "def";   // 变量拼接常量,不会存储到常量池。带有字符串变量的拼接,等价于StringBuilder的append
        String s4 = "abcdef";
        System.out.println(s3==s4);  // false
        String s5= s3.intern();
        System.out.println(s4==s5);  //true
  1. 如果s1和s2都是final类型的,那么s1和def的拼接,都是常量。
		final String s1 = "abc";
        final String s2 = "def";
        String s3 = s1 + "def";
        String s4 = "abcdef";
        System.out.println(s3==s4);
  1. new String("ab")创建了几个对象?两个。一个存放在堆中,一个存放在常量池中。

  2. new String("a")+new String("b")创建了几个对象?字符串a,b都在堆和常量池中,字符串变量拼接用的是StringBuilder。生成字符串,会生成字符串ab到堆中,所以总共是6个。

  3. s3是堆空间创造的变量,s4是常量池中对象,但是两个对象是相等的,属于同一个对象。该原理是因为String.intern()方法在1.8之后会将对象的引用地址放到串池,即串池中的对象和引用对象是同一份

        String s3 = new String("a") + new String("b");
        s3.intern();
        String s4 = "ab";
        System.out.println(s3 == s4);  // true
        System.out.println(s3.equals(s4));

包装类和对象池

        Integer i1 = 127;  //这种调用底层实际是执行的Integer.valueOf(127),里面用到了IntegerCache对象池
        Integer i2 = 127;
        System.out.println(i1 == i2);//输出true

        //值大于127时,不会从对象池中取对象
        Integer i3 = 128;
        Integer i4 = 128;
        System.out.println(i3 == i4);//输出false

        //用new关键词新生成对象不会使用对象池
        Integer i5 = new Integer(127);
        Integer i6 = new Integer(127);
        System.out.println(i5 == i6);//输出false

你可能感兴趣的:(JVM,面试,jvm,java,面试)