Java数据存储

来源:互联网 发布:idc 2012年手机数据 编辑:程序博客网 时间:2024/06/10 09:53
    最近遇到关于下列的题目很多,所以我觉得有必要来写写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)
原创粉丝点击