这样的东西,为什么得以流传? 
http://topic.csdn.net/u/20081123/12/f70f1632-24be-4caa-bc20-29cf8267afab.html

解决方案 »

  1.   

    不晓得,还是去看看《深入jvm》吧
      

  2.   

    对变量的内存分配不看类型看位置。有人问,基本类型变量和引用变量保存在哪里,这不是一个有效的问题。基本类型变量和引用变量都可能保存在stack或heap中,关键是看它们声明的位置——到底是域还是局部变量。我想了解一下,大家都是在自学吗?
      

  3.   


    JAVA的对象生存在堆中,而JAVA的各项成员变量,则根据JVM判断放栈还是掷堆
      

  4.   

    上大学的时候写过几次有关c、c++的blog,过了一段时间自己就发现了错误,从那以后就再也不写blog了,免得自欺又欺人。
      

  5.   

    楼主你要是强你就像ZangXT一样给大家普及普及JVM的深层知识, 你这种发言只能让大家觉得你在装B
      

  6.   


    另外,JVM的深层知识在你学习Java的前两年不需要知道!
      

  7.   

    原文及其错误:1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。 
    【栈(stack)与堆(heap)在Java的内存管理中是逻辑概念,这里“Ram中”说法不太好。“与C++不同,”不严谨】2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享,详见第3点。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
    【“另外,栈数据可以共享,详见第3点。”不知所云。其他基本正确,但是“运行时动态分配内存,存取速度较慢。”stack也是动态分配内存。】 3. Java中的数据类型有两种。一种是基本类型(primitive types), ……值得注意的是,自动变量存的是字面值,不是类的实例,即不是类的引用,这里并没有类的存在。如int a = 3; 这里的a是一个指向int类型的引用,指向3这个字面值。这些字面值的数据,由于大小可知,生存期可知(这些字面值固定定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存在于栈中。 
    【“不是类的实例,即不是类的引用”,看人了,对于初学者这是错误的。“引用”的大小是可知的。“如int a = 3; 这里的a是一个指向int类型的引用,指向3这个字面值。”什么东西阿,没有这样的说法。“字面值的数据”其中“的数据”删除;字面值……存在于栈中,基本的概念都错了!】既然基本的概念都错了,后面的错误就多了。
      

  8.   

    25楼,我只是回应TinyJimmy。
    “错误就指正他!”7楼已经说了。
    至于原作者不懂Java内存管理、包装类的问题、String str = "abc"与常量池就不说了。但是“5. 关于String str = "abc"的内部工作”。有很多是对的,而且对的和错的搅和在一起。
      

  9.   

    感觉还是稍微看点c的基础的好,首先要真正了解new delete,就知道里面东西错的太多,我没有看完50%就关了。居然说“查找相等的内存”之类的,不好评价了,基本上对内存没有什么概念。
      

  10.   

    楼主要详细了解请看这个 http://topic.csdn.net/u/20081123/12/f70f1632-24be-4caa-bc20-29cf8267afab.html通俗的说是值传递
    基本数据类型采用值传递方式向方法传递参数
    基本类型的变量存储在"栈"中引用传递
    对象类型采用引用传递方式向方法传递参数
    对象类型的变量值存储在"堆"中
      

  11.   


    没注意看帖子内容
    不说离题,只说内容,
    如果你说全部错误,我还正接受不了,
    原话是《 深入浅出JDK6.0  》  涂传滨    电子工业出版社   第32页第11行,一字未变
    数据结构与算法(Java版)  一个美国人写的
    我不是科班出身,编程全部是看书的,向你请教正确答案
      

  12.   

    值传递 
    基本数据类型采用值传递方式向方法传递参数 
    基本类型的变量存储在"栈"中 引用传递 
    对象类型采用引用传递方式向方法传递参数 
    对象类型的变量值存储在"堆"中 
    1、Java中只有值传递,Java创始人说的,其他的说我们都不听,也不争论了。
    2、class A{int i;int j}这些i、j在哪里存储?告诉涂传滨,在heap中。
      

  13.   

    三鹿奶粉有毒,
    如果我国的书籍的错误有索赔制度,
    垃圾书籍就少得多。轻轻地呼吁,版主将那篇《Java栈与堆》删除,
    居然有人推荐,我都不知道是什么人在推荐。
      

  14.   

    其实对于单纯学java的人来说, 已经不太重要了。 重要的是明白String s = "abc";这个经典案例就行了。
    对堆和栈有所了解就好, 毕竟大多数人要做的是企业应用, 不是系统应用, 研究到内存那个级别没有太大的实用价值。
      

  15.   


    我不认识Java的创始人,也懒的去读一堆E文
    关于你上面的两个说法,我的意见是:
    1.Java中一切皆对象,操纵的标识符实际上是对象的一个“引用”(reference)。任何事物都是“按值传递的没错”,也许这个一种精确但令人费解的解释,但我认为我这种简化的概念上的理解并没错。   (Thiking In Java 4)  21页页末
    2.class A{int i;int j}  i、j存储在heap中没错,但是 JAVA中任何传递对象的场合一样,这里传递的实际上是应用,对于基本数据类型来说是一个例外,通常,尽管传递的是对象,实际上传递的是对象的引用。(Thiking In Java 4)  27页页末
      

  16.   


    按照你的观点,你不可能知道变量的生命周期,
    于是你不可能理解局部类(local class)中只能访问外包方法(局部类所在方法)的final局部变量。
    你说一下,位于方法内部的局部类,为什么只能访问操作y而不能操作x?
    void go(int x,final int y)这些东西没有什么高深的地方,基础知识而已。
      

  17.   

    下面的一个代码可以说明JAVA参数传递的问题:class Arg{
    Arg(){
    i=0;
    }
    int i;
    }
    public class ArgumentPass {
    public static void testPrimitive(int x){
    //这里的代码不能改变参数传递前的原值,说明它修改的只不过是一个拷贝
    x++;
    }
    public static void testObject1(Arg x){
    //这里的代码真实地修改了参数对象里面的成员值,说明对象参数并不是拷贝,而是对象指针(引用)
    x.i++;
    }
    public static void testObject2(Arg x){
    //虽然重新给参数x赋予了新的对象,但其实没起作用,说明x里面放的指针值(引用值)也只不过是一个拷贝。
    x=new Arg();
            x.i++;
    }

    public static void main(String[] args) {
    int y=0;
    System.out.println("before call:"+y);
    testPrimitive(y);
    System.out.println("after call:"+y);
    Arg a=new Arg();
    System.out.println("before call:"+a.i);
    testObject1(a);
    System.out.println("after call:"+a.i);
    Arg b=new Arg();
    System.out.println("before call:"+b.i);
    testObject2(b);
    System.out.println("after call:"+b.i);
    }
    }
    针对上面的例子再打比方:
    1、testPrimitive
    传递原始类型参数,相对于调用者手上有一个纸片,上面写着参数值。然后它复制了一个同样的纸片给被调用者。因此被调用者在这个纸片上乱涂乱改也对调用者没有任何影响。
    2、testObject1和testObject2
    传递对象。例子是图书馆,对象假设是一本书,调用者自己有一个纸片上记录了这本书的位置,比如“第1排第2行第1格”。然后它复制了一张纸片给被调用者。被调用者可以根据纸片上的值找到这本书,然后在上面乱涂乱改,这对调用者是起作用的(正如testObject1所示)。但是,如果被调用者仅仅是在纸片上乱涂乱改,对调用者一点作用也没有(正如testObject2所示)。无论是什么样的说法,不管是传值、传指针、传引用、传地址,最管总的说法是传-值拷贝。对于primitive,传的是数值拷贝,对于对象,传的是地址值拷贝
      

  18.   

    51楼的例子很好,要是能画个内存图就完美了.
    记得Core java上有图形说明,很清晰.
      

  19.   

    以后我遇到说“按引用传递”的,
    我首先问他,你说的是TIJ的“按引用传递”,还是计算机科学的“按引用传递”。TIJ的“按引用传递”,它看见C语言的学习者,他会说,指针传递也是TIJ的“按引用传递”。
      

  20.   

    请看看什么是“按引用传递”和“按值传递 ”。C++代码#include <stdio.h> 
    void change(int i)  {  i/=2; } //
    void change1(int* i){  *i/=2; }
    void change2(int &i){  i /=2;}
    void main(void){
      int a=100;printf("before:a=%d ",a);
      int *p1;
      p1 = &a;  printf("p1=%d\n\n",p1);  change(a);   printf("after change(a):   a=%d\n",a);
      change(*p1); printf("after change(*p1): a=%d and %d\n",a,p1);
      change1(p1); printf("after change1(p1): a=%d and %d\n",a,p1);
      change1(&a); printf("after change1(&a): a=%d and %d\n",a,p1);
      change2(a);  printf("after change2(a):  a=%d and %d \n",a,&a);
      change2(*p1);printf("after change2(*p1):a=%d and %d \n",a,p1);    
    }
      

  21.   

    这篇文章根本不值得一驳,因为它基本上就没有说对的内容。
    但实在不忍心看到这么多初学者被这篇超级大忽悠文章误导,还是浪费点口水吧。就拿"栈中的数据可以共享"这个荒谬的观点开刀。文章说道
    int a = 3; 
    int b = 3; 
    编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。 简直笑死我了!
    你打开class文件,这2句就4个字节,内容是“06 3B 06 3C”
    对应的虚拟机指令就是:
        0  iconst_3
        1  istore_0 [a]
        2  iconst_3
        3  istore_1 [b]
    学过计算机原理的人都知道,
    第1个字节06 iconst_3是一个指令,这个指令就是让CPU把寄存器放上3的值
    第2个字节3B istore_0也是一个指令,就是让CPU把寄存器的值放到第1个变量的内存中
    第4个字节3C istore_1也是一个指令,就是让CPU把寄存器的值放到第2个变量的内存中这里可以看到JAVA虚拟机的一个小技巧,它把一些对常用常量(比如0,1,2,3,4,5)的操作直接定义成了指令,而不是传统的操作指令后带操作数。
    目的是减少指令长度。有心的人再用 int a = 6...试,根本就没有iconst_6的指令!
    而是bipush 6,机器码10 06, 2个字节,10就是bipush, 06就是操作数6,就是传统的指令+操作数。大家用脑子想想“在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址”这句话,
    问自己一个问题:这样说起来容易,虚拟机实现起来呢?
    再问一个问题:这样做是不是脱裤子放屁,多此一举呢?
      

  22.   

    新手~~不太清楚~~刚刚开始学习java~~
    ls各位都那么牛~~很精彩的一个贴阿~
      

  23.   

    首先要理解jvm是基于栈的,寄存器就不要提了。
      

  24.   

    希望大家指出
    http://topic.csdn.net/u/20081127/23/bd9ca56e-44d3-4f94-80f7-88f469f6dd79.html
    中的错误。
      

  25.   


    嗯,我这个是说错了。jvm spec上叫“Operand Stack”,翻译过来是“操作数 栈”
      

  26.   


    同意这种简单的提法:
    1 .    java只有传值,对象靠引用来调用,对象参数传递的时候传递“引用”的值,用这点解释足够了,概念创造越多初学者越糊涂。2.     至于数值存放在哪里?只要记住“所有局部变量存放在栈中,所有对象存堆中”就可以了,具体实例可以据此引申出来。
         a 局部变量如果是基本类型,则存栈中;如果是对象类型,实际上操作的是一个引用,引用存栈中,对象存堆中。
         b 对象存堆中的含义就是对象的所有字段存堆中,所以对象的字段不管是基本数据类型和引用一律在堆中,引用指向的对象自然也在堆中。
      

  27.   

    这些知识都是最基础的!
    做C++的应该都知道的,不知道为什么在JAVA区会有如此激烈的讨论!