java中局部变量int a=3在栈空间是怎么储存的,编译时a的表现形式是啥?,String str=“abc”中的str是不是跟c中的指针一个性质

解决方案 »

  1.   

    局部变量 int a = 3;
    变量名a和3是同时储存在栈里面,
    a指向3。如果这时,也来一个局部变量 int b = 3;
    那么程序此时就不会重新为3开辟栈空间,
    而是让b也指向a所指向的3。之后如果b或者a做运算的话
    例:b=b+3;
    那么程序会另外开辟一个栈空间存放6,
    然后b指向储存6的栈空间。
    ------------------------------
    String str=“abc”中str是跟c指针有相同的性质。
      

  2.   

    java 分栈 和 堆
    int a=3, 变量a 在栈中, 3在堆中,a指向3,
    String str1=“abc”;
    String str2=“abc”;
    str1,str2 都指向堆中的abc,abc在堆中只有一个,同一地址
      

  3.   

    java中的引用变量可以认为是c中的指针变量。Student student = new Student(). 
    studnet指向new Studnet()这个对象,所以可以认为student是指向它的指针变量
      

  4.   

    吐血了,为什么这么多不一样的结论,那天看到一个帖子分析的,我取一段,"打开class文件,int a=3就4个字节,内容是“06 3B第1个字节06 iconst_3是一个指令,这个指令就是让CPU把寄存器放上3的值
    第2个字节3B istore_0也是一个指令,就是让CPU把寄存器的值放到第1个变量的内存中,不是很懂,你们的说法好像都被否定了,有人更明白的吗
    "
      

  5.   

    大体分析一下
    1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。
    //栈都是由运行环境来处理的,这点C++和java没有什么不同.对于堆,不过java多了个GC.
    2.这里的堆和栈首先要明确是虚拟机栈,和寄存器根本不是一个级别的东西,就别比较了.
    3.栈数据共享好像是作者自己创造的概念.而且给基本类型也引入了"引用"的概念,不知道出于何种打算.
    java虚拟机规范中说:Primitive values do not share state with other primitive values. A variable whose type is a primitive type always holds a primitive value of that type.
    看一下实际的处理情况:
       int a=3;
       int b=3;
       int c=65535;
       int d=65535;
       int e=32330;
       int f=32330;
    看对应的虚拟机指令,可以知道变量里实际存储的是什么:
    Code:
       0: iconst_3 //3
       1: istore_1
       2: iconst_3 //3
       3: istore_2
       4: ldc #2; //int 65535
       6: istore_3
       7: ldc #2; //int 65535
       9: istore 4
       11: sipush 32330
       14: istore 5
       16: sipush 32330
       19: istore 6
       21: return
    可以看出每个变量保存自己的值.(具体指令的意义参考java虚拟机规范)
    这里要注意的是对于int值,如果它大于short能表示的范围,则放到常量池中去.
    11: sipush 32330
       14: istore 5
    这句,11-13,正好是3个字节的指令大小,一个字节是sipush指令,2个字节用来存储32330这个数.两次使用到这个数,都是把它直接存给变量的,所以原贴中一直强调的"栈中共享" 的说法明显不对.
    对于65535,它是大于两个字节的,编译的时候把它放入常量池部分,而把取这个数的指令写为ldc#2,我感觉这样一个直观的好处是减少了指令代码的长度.尤其是多次使用到一个相同的数时.   其实,java 对变量的处理很简单,基本类型变量存放值,引用类型存放一个"引用" (实际就是一个"指针" ,以前曾经和别人讨论过,很多人认为是个"句柄",并举了很多证据,但是我后来看到了sun的java hotspot白皮书,里面直接说明了,引用实际就是一个c的"指针" ,使用句柄需要多次间接查找,会带来效率的瓶颈,当然这个指针并不是直接指向实际的对象,实际指向的是一个两个机器字大小的对象头,对于数组是3个机器字大小的对象头,因为还要保存数组的长度) .
    java设计时保留基本类型而不把一切都设计为对象,就是出于效率考虑,如果对于基本类型再通过"引用"去查找值,何苦呢?
    4.String也是包装类? 这应该也是作者自己定义了包装类的概念,去java语言规范里看看什么是wrapper class.
    5.Integer i = 3;编译器如何处理?
    sun的编译器是这样处理的:
    Integer i=Integer.valueOf(3);
    而不是通过new来创建了,因为Integer类中静态的创建了-128~+127之间的对象,需要的数在这个范围之内时,直接返回,此范围之外的数才通过new来创建.
    简单测试.
    Integer i=3;
    Integer j=3;
    我们测试i==j会发现它是true.
    String str = new String("abc");去看String类的构造方法会发现,这里用的是String(String original)来创建的,也就是说用一个String来创建一个String,"abc"编译的时候编译器会把它加入常量池部分.不知道原贴所谓的包装类是如何得来的.
    csdn 的java版有个“推荐”的专门讲String常量池的帖子,很不错。
    5."JVM发现在栈中没有存放该值的地址,便开辟了这个地址,并创建了一个新的对象,其字符串的值指向这个地址。 "又没有分清编译器和虚拟机的职责分配.编译器会把"abc"放入常量池,并记住它在常量池中的位置,别的地方用到的时候编译器直接生成ldc指令来制定了,不会让jvm去找,去开辟地址等等.
    7.原贴明显不知道常量池的存在,好像是把常量池的数据都认为是"栈"的了.
       java新增了StringBuilder来处理可变字符串,如果不需要多线程环境,应该首先选择这个,而不是StringBuffer,一个zangTX大侠总结的.
      

  6.   

    JPanel p=new JPanel(new BorderLayout());
    问个问题哈,new的对象里面new另外一个东西.这个在java里面有啥学术名称没
    譬如说new BufferedReader(new InputStreamReader(new FileInputstream()));
    小弟愚钝,求指教