看了很多资料都说的很含糊,  希望高手帮忙指点下.   
   
     特别是他们在栈内存与堆内存中是如何调用的......主要就是这里有点含糊.......忘高手指点!       谢谢!!!      比如 什么一个引用类型 NEW一个之后 又使用了堆内存啊, 然后那个什么栈内存又是引用的堆内存的值啊.....混乱中...

解决方案 »

  1.   

    懂c的话更好理解一点
    int *a = (int*)malloc(sizeof(int)*10);a自己只是一个指针,也是一个变量,存在栈
    后面malloc的那块空间在堆上
    a指向那块空间转到java
     A  a = new A();
    其实是一样的,尽管都说java没指针,不过我觉得当指针那么理解也无所谓。
      

  2.   


    值类型: a (栈上) 自己存的就是一个value
    引用类型: a (栈上) 存的是一个堆上的地址
      

  3.   

    堆中存放的是实际的对象,这个对象占有了一定容量的内存,栈中的引用指向堆中内存的地址,A a = new A(),new A()生成了A的一个实例(堆中存放),而a指向A的实例(a在栈中存放)
      

  4.   

    2楼只是用C作为引入简单的讲了下,其实没有什么大错
    对象本来就是放在堆区的,变量也仅仅只是一个引用,自己去输出一下看看吧,能理解C里面指针的概念就很容易理解java的引用,java要简单的多!!!
    你问的静态变量我告诉你,在java中放在常量池里面,和静态块一样,常量池全部都在栈内
    至于对象的成员变量,你这个问题问的一点意义都没有,对象被放到了堆区,对象的属性你说该放哪里?
    先说到这里了,还有成员变量被static 、final等修饰等等各种情况再说下去没就底了
      

  5.   

    1:好,你说了成员变量在堆里,所以变量不全是在栈里,这点上他就错了
    2:常量池全部在栈里,这个是第一次听说,带高手求证
    3:曾经有高手指出过:java的指针是指向的是一个两个机器字大小的对象头
      

  6.   

    根据《深入JAVA虚拟机》书中描述:常量池是属于类型信息的一部分,类型信息也就是每一个被转载的类型,这个类型反映到JVM内存模型中是对应存在于JVM内存模型的方法区中,也就是这个类型信息中的常量池概念是存在于在方法区中,而方法区是在JVM内存模型中的堆中由JVM来分配的。常量池在栈里这个说话真恶心!
      

  7.   

    谢谢楼上的指导,继续说
    4:静态变量不是放在常量池里的,常量池放的是些基本的整数和编译后的String常量,常量池在栈里这个说法很可笑了
    5:成员变量没有static一说
    6:即使时是用了final,也只是进行了编译器优化,因为final能够修饰所有变量,试想它修饰局部变量和其他局部变量一样也是方法完就销毁的,没有任何持久存在的必要,如果修饰成员变量,每个对象new出来也包含它在有的
      

  8.   

    楼主可以参看Java编程思想里面堆和栈这一块内容的讲解,自己好好理解去。问别人得到的知识别人片面的理解而已,还是自己去理解的好
      

  9.   

    常量池具体在哪里我也证明不了,只不过我理解的常量池是在栈里面,汇编里面栈的概念
    静态变量不是放在常量池里的,是放哪里呢?
    成员变量没有static一说?单例模式写一个看看有没有static的即使时是用了final,也只是进行了编译器优化
    试想它修饰局部变量和其他局部变量一样也是方法完就销毁的final修饰的变量 生命周期还是在去测试下吧,写个内部类测试下就明白了
      

  10.   


    1.常量池具体在哪里我也证明不了,只不过我理解的常量池是在栈里面,汇编里面栈的概念
    错误。常量池在方法区。sun jvm中的PermGen。
    http://zangxt.javaeye.com/blog/4722362.静态变量不是放在常量池里的,是放哪里呢?
    方法区。 3.成员变量没有static一说?单例模式写一个看看有没有static的
    严格说java根本没有成员变量之说。4.即使时是用了final,也只是进行了编译器优化
    试想它修饰局部变量和其他局部变量一样也是方法完就销毁的final修饰的变量 生命周期还是在去测试下吧,写个内部类测试下就明白了
    final修饰的变量,方法没了肯定没了。内部类是复制了一份,并不是局部的final变量了。final在这种情况下起到一个锁定作用。
      

  11.   

    关于内部类方法访问局部变量时,局部变量需要声明为final的,这个原因比较容易理解。
    看下面的代码:
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JOptionPane;public class Test extends JFrame {    private JButton button;    public Test() {
            final int localInt = 8;
            final StringBuilder builder = new StringBuilder("builder");
            button = new JButton("Test");
            button.addActionListener(new ActionListener() {            public void actionPerformed(ActionEvent e) {
                    JOptionPane.showMessageDialog(Test.this, builder);
                    JOptionPane.showMessageDialog(Test.this, localInt);
                }
            });
            this.add(button);
            this.setSize(100, 100);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setVisible(true);
        }    public static void main(String[] args) {
            new Test();
        }
    }
    这里button.addActionListener(new ActionListener() {            public void actionPerformed(ActionEvent e) {
                    JOptionPane.showMessageDialog(Test.this, builder);
                    JOptionPane.showMessageDialog(Test.this, localInt);
                }
            });
    访问了局部变量。
    很明显,因为actionPerformed是当按钮单击时才调用的方法,而那时候Test构造方法早就执行完了,而
    方法中的局部变量自然在方法调用完毕后不存在了。
    那怎么办呢?于是java从语法上施加了一个限制,要求内部类中方法访问的局部变量必须是final的。
    因为final变量是不会被改变的,所以java编译器在这偷偷的复制了一份给内部类的对象。
    看反编译代码:
    内部类Test$1.classCompiled from "Test.java"
    class Test$1 extends java.lang.Object implements java.awt.event.ActionListener{
    final java.lang.StringBuilder val$builder;final Test this$0;Test$1(Test, java.lang.StringBuilder);
      Code:
       0: aload_0
       1: aload_1
       2: putfield #1; //Field this$0:LTest;
       5: aload_0
       6: aload_2
       7: putfield #2; //Field val$builder:Ljava/lang/StringBuilder;
       10: aload_0
       11: invokespecial #3; //Method java/lang/Object."<init>":()V
       14: returnpublic void actionPerformed(java.awt.event.ActionEvent);
      Code:
       0: aload_0
       1: getfield #1; //Field this$0:LTest;
       4: aload_0
       5: getfield #2; //Field val$builder:Ljava/lang/StringBuilder;
       8: invokestatic #4; //Method javax/swing/JOptionPane.showMessageDialog:(Ljava/awt/Component;Ljava/lang/Object;)V
       11: aload_0
       12: getfield #1; //Field this$0:LTest;
       15: bipush 8
       17: invokestatic #5; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       20: invokestatic #4; //Method javax/swing/JOptionPane.showMessageDialog:(Ljava/awt/Component;Ljava/lang/Object;)V
       23: return}首先我们就能看到类中定义的两个字段:
    final java.lang.StringBuilder val$builder;  //指向StringBuilder引用
    final Test this$0;  //指向内部类所在的类Test对象的引用
    而且该类的构造方法为Test$1(Test, java.lang.StringBuilder);
    在构造方法中对这两个字段进行初始化。
    对于 final int localInt = 8;呢,这个不用复制了,常数编译的时候就替换了。看15: bipush 8
       17: invokestatic #5;即可很明显,actionPerformed中访问的是Test$1自身的field。再看Test构造方法中注册事件监听的代码:
    new #5; //class javax/swing/JButton  创建JButton
       18: dup
       19: ldc #6; //String Test
       21: invokespecial #7; //Method javax/swing/JButton."<init>":(Ljava/lang/String;)V
       24: putfield #8; //Field button:Ljavax/swing/JButton;
       27: aload_0
       28: getfield #8; //Field button:Ljavax/swing/JButton;
       31: new #9; //class Test$1,创建内部类的对象
       34: dup
       35: aload_0
       36: aload_2
       37: invokespecial #10; //Method Test$1."<init>":(LTest;Ljava/lang/StringBuilder;)V  builder在这传递给Test$1的构造方法,引用复制了一份,ok
       40: invokevirtual #11; //Method javax/swing/JButton.addActionListener:(Ljava/awt/event/ActionListener;)V
      

  12.   

    看看thinking in java的前三章就知道了
      

  13.   

    new 出来的对象都分配在堆内存中 ,理解一下内存的使用机制就好记住了 
      

  14.   

    楼主去看下scjp吧 Java的基础知识还是要看人家的问题都是哪些的。我原来也是一知半解的。
    class B {
    int id;
    public B b;

    public B(id){
    this.id = id;
    }

    public void print(){
    System.out.println("this.id===>"+id);
    }
    }public class A{
    int id;
    B b;
    public A(int i, B b) {
    this.id = id;
    this.b = b;
    }
    public static void main (String[] args){
    B b1 = new B(1);
    B b2 = new B(2);
    B b3 = new B(3);

    b1.b = b2;
    A a = new A(0,b1);
    a.b1.print();    //this.id===>1
    a.b1.b.print();  //this.id===>2

    b1.b = b3;
    a.b1.print();    //this.id===>1
    a.b1.b.print();  //this.id===>3

    b1 = b2;
    a.b1.print();    //this.id===>1
    a.b1.b.print();  //this.id===>3
    }
    }
    博客内有更精彩的内容