zoukankan      html  css  js  c++  java
  • Java 常量池

    Java 常量池

    常量池入口放置 u2类型的数据,代表常量池容量计数值 constant_pool_count 。 u2类型是 什么

    基本类型包装类和常量池

    1. Byte Short Integer, Long Character, Boolean:

    Integer如果超过范围 就会去创建新的对象

      Integer i1 = 40;
      Integer i2 = 40;
    
     Integer i3 = 400;
     Integer i4 = 400;
    
      System.out.println(i1 == i2);   //true
     System.out.println(i3 == i4);   //false 
    
    
            double d1 = 1.1;
            double d2 = 1.1;
    
            Double d3 = 1.1;
            Double d4 = 1.1;
            System.out.println(d1 == d2); // true
            System.out.println(d3 == d4); // false
    
    

    两种浮点数类型的包装类Float,Double并没有实现常量池技术。

    Double i1=1.2;
    Double i2=1.2;
    System.out.println(i1==i2);//输出false
    
    
    Integer i1 = 40;
    Integer i2 = 40;
    Integer i3 = 0;
    
    Integer i4 = new Integer(40);
    Integer i5 = new Integer(40);
    Integer i6 = new Integer(0);
    
    System.out.println("i1 = i2	"+ (i1==i2));               //true
    System.out.println("i1 = i2 + i3	"+ (i1 == (i2 + i3))); //true
    System.out.println("i4 = i5	"+ (i4==i5));               //false
    System.out.println("i4 = i5 + i6	"+ (i4 ==i5 + i6));     //true
    System.out.println("40 = i5 + i6 "+ (40 == i5+i6));       // true
    
    

    首先i5和i6进行自动拆箱操作,进行数值相加,即i4 == 40。
    然后Integer对象无法与数值进行直接比较,所以i4自动拆箱转为int值40,最终这条语句转为40 == 40进行数值比较。

    String类和对象池

    String s1 = "hello";
    String s2 = new String("hello");
    
    System.out.println(s1 == s2);   //false
    

    s1 常量池 中对象; s2 在堆上创建 新对象。

    String s3 = "hello";
    String s4 = "world";
    String s5 = "helloworld";
    String s6 = s3+s4;
    
    System.out.println(s5 == s6); //false
    
    

    String 重载了 + 操作符 字符串拼接相当于 重新创建新的字符串。 因此, "hello" + "world" 相当于创建 新的 "helloworld"

    java基础:字符串的拼接 http://www.jianshu.com/p/88aa19fc21c6

        public static final String S7 = "ab";
        public static final String S8 = "cd";
    
        public static void main(String[] args){
    
            String s9 = "abcd";
    
            System.out.println(s9 == (S7+S8));  //true
        }
    
    

    S7 S8为常量。 编译时确定。

        public static final String S7;
        public static final String S8; 
    
        static {
            S7 = "ab";
            S8 = "cd";
        }
    
        public static void main(String[] args){
    
            String s9 = "abcd";
    
            System.out.println(s9 == (S7+S8));// false
    
        }
    
    
    

    // 此时,由于 S7 S8没有 定义时赋值, 相当于 变量,值在运行时确定。而不是编译时。

    String s1 = new String("xyz");
    

    1.类加载,一个类只进行一次。 "xyz"在类加载时就已经创建并驻留了(如果该类被加载之前已经有"xyz"字符串被驻留过则不需要重复创建用于驻留的"xyz"实例)。
    驻留的字符串是放在全局共享的字符串常量池中的。
    2.在这段代码后续被运行的时候,"xyz"字面量对应的String实例已经固定了,不会再被重复创建。

    所以这段代码将常量池中的对象复制一份放到heap中,并且把heap中的这个对象的引用交给s1 持有。

    这条语句创建了2个对象。 一个堆上的对象,一个引用对象 ?

    String 常量池 String.intern()用法

    • 直接使用双引号声明出来的String对象会直接存储在常量池中。
    • 如果不是用双引号声明的String对象,可以使用String提供的intern方法。intern 方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池中
    //Other.java
    package basics.other;
    
    public class Other {
        public static String hello = "hello";
    }
    
    
    //StringTest.java
    package basics;
    public class StringTest {
        public static void main(String[] args){
            String hello = "hello";
            String lo    = "lo";
            System.out.println(hello == "hello");                   //true
            System.out.println(basics.other.Other.hello == hello); //true
            System.out.println(Other.hello == hello);            //ture
            System.out.println(hello == "hel"+"lo");            //true
            System.out.println(hello == "hel"+lo);             //false
            System.out.println(hello == ("hel"+lo).intern());  //true
        }
    }
    class Other{
        static String hello = "hello";
    
    }
    

    在同包同类下,引用自同一String对象.
    在同包不同类下,引用自同一String对象.
    在不同包不同类下,依然引用自同一String对象.
    在编译成.class时能够识别为同一字符串的,自动优化成常量,引用自同一String对象.
    在运行时创建的字符串具有独立的内存地址,所以不引用自同一String对象. “+” 操作符 创建新对象。

    《深入Java虚拟机 》 第6章 Java class文件
    《深入理解Java7》 第8章 Java源代码和字节代码操作
    《深入理解Java虚拟机 JVM高级特性与最佳实践》6.3

    参考资料

    http://www.jianshu.com/p/c7f47de2ee80

    Java中的自动装箱与拆箱
    http://droidyue.com/blog/2015/04/07/autoboxing-and-autounboxing-in-java/

    Java堆、栈和常量池以及相关String的详细讲解(经典中的经典) (未看)
    http://www.cnblogs.com/xiohao/p/4296088.html

    深入解析String#intern
    http://tech.meituan.com/in_depth_understanding_string_intern.html

  • 相关阅读:
    eclipse下配置hadoop环境
    eclipse下安装hadoop伪分布式集群
    ubuntu安装eclipse步骤
    Fiddler修改抓包请求
    Fiddler抓包(以谷歌浏览器、安卓手机为例)
    whistle抓包-数据包分析
    whistle手机抓包(以安卓手机为例)
    whistle浏览器抓包(以火狐浏览器为例)
    whistle安装
    Jmeter结构体系及运行原理
  • 原文地址:https://www.cnblogs.com/ironbrady/p/6388814.html
Copyright © 2011-2022 走看看