Java数据存储

    最近遇到关于下列的题目很多,所以我觉得有必要来写写Java中基本类型和引用类型的一些东西。
    先来看看下列的题目,会输出的是什么?
public class StringDemo{
  private static final String MESSAGE="taobao";
  public static void main(String [] args) {
    String a ="tao"+"bao";
    String b="tao";
    String c="bao";
    System.out.println(a==MESSAGE);
    System.out.println((b+c)==MESSAGE);
  }
}
    想到答案了么?答案是true、false。我们先来看看程序运行时,对象是怎么进行放置安排的呢?
    1)寄存器。这是最快的存储区,因为它位于处理器内部,但是寄存器数量很少,所以寄存器根据需求进行分配。然而,你却不能直接控制,也不会在程序中感受到它的存在。
    2)堆栈。位于通用RAM(随机访问存储器)中,但通过堆栈指针可以从处理器那里直接支持。堆栈指针若向下移动,则分配新的内存。向上移动,则释放那些内存,这种快速的分配存储方法,仅次与寄存器。但是系统必须知道这些存储在堆栈内所有项的生命周期。基本类型变量和值、对象引用都会在堆栈里。
    3)堆。一种通用的内存池(也位于RAM区),用于存储所有Java对象。编译器不需要知道那些在堆的所有项的生命周期。所以,只要写new,就会在自动堆中进行分配空间。
    4)常量存储。常量会存在在常量池这个特殊的存储区域,值的一提常量池在堆中。
    5)非RAM存储。如果数据完全存活在程序之外,那么它可以不受程序任何控制,在程序没有运行时也可以存在。其中两个基本例子就是流对象和持久化对象。这个会出现在JDBC和Hibernate中。
//i和j其实都是存储在堆栈中,都是指向8这个数,另外8也是存储在堆栈
    int i=8;
    int j=8;
    System.out.println(i==j);//所以输出也是true
    String str1="123";
    String str2="123";
    String str3=new String("123");
    String str4=new String("123");
    System.out.println(str1==str2);//true
    System.out.println(str3==str4);//false
    第二段代码,这里String str1="123"创建的时候会在常量池先寻找是否存在"123"这个字符数组,如果没有就在常量池中创建,然后就引用给str1。接下来String str2="123"就会在常量池中寻找,找到了就把引用给str2。
    而str3、str4[创建过程](https://zhuanlan.zhihu.com/p/27626724),所以会有问题问你创建过程的会产生几个对象。
    所以让我们回到最初的问题,我们开始分析这道题,MESSAGE 成员变量及其指向的字符串常量肯定都是在栈内存里的,变量 a 运算完也是指向一个字符串“ taobao ”啊?是不是同一个呢?这涉及到编译器优化问题。对于字符串常量的相加,在编译时直接将字符串合并,而不是等到运行时再合并。也就是说String a =  "tao" + "bao" ;和String a =  "taobao" ;编译出的字节码是一样的。所以a和MESSAGE指向的是同一个字符串。
    而对于后面的(b+c)又是什么情况呢?b+c只能等到运行时才能判定是什么字符串,编译器不会优化,想想这也是有道理的,编译器怕你对b的值改变,所以编译器不会优化。运行时b+c计算出来的"taobao"和栈内存里已经有的"taobao"是一个吗?不是。b+c计算出来的"taobao"应该是放在堆内存中的String对象。这可以通过System.out.println((b+c)== MESSAGE);的结果为false来证明这一点。如果计算出来的b+c也是在栈内存,那结果应该是true。Java对String的相加是通过StringBuffer实现的,先构造一个StringBuffer里面存放”tao”,然后调用append()方法追加”bao”,然后将值为”taobao”的StringBuffer转化成String对象。StringBuffer对象在堆内存中,那转换成的String对象理所应当的也是在堆内存中。
    最后推荐一下一个新手值的看的[专栏](https://zhuanlan.zhihu.com/easyJava)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值