Java面试必知:Java中 String和Integer内存存储问题

String的内存存储

  • String a=“a” 可能创建一个对象或者不创建对象, 如果"a"这个字符串在java String池里不存在,会在java String池创建这个一个String对象(“a”).如果已经存在,a直接reference to 这个String池里的对象。
  • String str1 = new String(“ABC”) 至少创建一个对象,也可能两个。因为用到new 关键字,会在heap创建一个 str1 的String 对象,它的value 是 “ABC”.同时,如果"ABC"这个字符串在java String池里不存在,会在java String池创建这个一个String对象(“ABC”).
  • String 有一个intern() 方法,native,用来检测在String pool是否已经有这个String存在。
  • 对于new jvm会直接分配新的空间
  String a=new String("女");
        String a1="女";
        String a2="女";
        System.out.println(a==a1);
        System.out.println(a1==a2);
        /**
         * false 因为 a 开辟了俩个空间 一个在堆,一个在常量池,a指向堆地址,而a1指向常量池地址,所以不一样
         * true  因为 a1 和 a2 都是指向常量池中的 一块内存
        */
        String s7 = "hello";
		String s8 = "he" + "llo";
		System.out.println(s7==s8);    

		String s9 = "hello";
           String s10 = "he";
           String s11 = s10 + "llo";
           System.out.println(s9==s11);  

           String s12 = "hello";
           String s13 = "he" + new String("llo");
           System.out.println(s12==s13);  
           
           String s14 = s13.intern();
           System.out.println(s12==s14); 
           System.out.println(s13==s14);
           /**
            *true
			*false
			*false
  			*true
			*false
			**/+运算左右俩端都是常量时,javac会进行字符串折叠,结果会优先从常量池中找
			而存在变量或者new时在堆区开辟

注意:

  1. String a=“a”+“b” javac会进行字符串折叠, 相当于a=“ab” 所以创建一个对象
  2. String a= b+c 当俩边为对象引用时,在堆空间开辟,不在常量池中开辟
  3. String的intern() 方法 a.intern() 查看常量池中是否有与a equals的值,有则返回地址,将a变量的值移到变量池中(没有在变量池中开辟,并将a指向此空间)

Integer的内存存储

  • Integer是int的封装类,一般来说基础变量(int)赋值给Integer对象将自动装箱(Auto Boxing)并为Integer对象分配堆空间。因此即使基础变量值一样,封装类对象指向不同地址。
  • JVM为了节省空间, 当Integer的值落在-128~127之间时,如Integer i1 = 2; Integer i2 = 2;此时JVM首先检查是否已存在值为2的Integer对象.如果是,则i2直接是引用已存在对象,即i2 == i1。
  • 事实上, Integer已经默认创建了数值[-128~127]的Integer缓存数据。所以使用Integer i1=2时,JVM会直接在该在对象池找到该值的引用。
  • 当 Integer 和基本类型进行比较时,会进行拆包.按基本类型进行比较
  • 对于显式的new ,JVM将直接分配新空间。
    Integer i1 = 2;
    Integer i2 = 2;
    Integer i3 = 300;
    Integer i4 = 300;
    int  i5=300;
    System.out.println("i1 = i2? " + (i1 == i2)); 
    System.out.println("i3 = i4? " + (i3 == i4)); 
    System.out.println("i4 = i5? " + (i4 == i5)); 
    /**
    * true
    * false
    * true  和 基本类型进行比较时,会自动拆包(此处是char byte等也是true)
    * /

基本数据类型

  • 作为对象的成员变量 存放在堆中
  • 作为方法的局部变量 存放在栈中
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值