说些什么呀?s和string是什么?实例变量还是局部变量???

解决方案 »

  1.   

    就是说s 和  string  都指向  "Hello world!"  。
    很简单,也很容易遗忘的知识点。
      

  2.   

    好好。。多多发些有意义的贴,,,DAY DAY UP
      

  3.   

    楼主精神可嘉,值得多多鼓励。
    建议还可以适当更加深入一些,如
    String s1 = "This is cool!";
    String s2 = "This is cool!";
    String s3 = new String("This is cool!");
    s1 = s2;
    s3 = "This is cool!";
    这样的代码共有产生多少String实例,有多少对象可以被GC等等。UP~UP~
      

  4.   

    String s1 = "This is cool!"; Objnum=1;
    String s2 = "This is cool!"; Objnum=2;
    new String("This is cool!"); Objnum=3;
    String s3 = new String("This is cool!");Objnum=4;
    s1 = s2; Objnum=4;
    s3 = "This is cool!"; Objnum=5;Object number is 5, isn't it right?
      

  5.   

    object number(s1)=object number(s2)=object number(s3)
      

  6.   

    “我们并没有声明一个String对象,我们只是声明了一个只能指向String对象的引用变量。”"Hello world!"对象是怎么来的?它确确实实是无到有,所以这个工程不仅仅是“我们只是声明了一个只能指向String对象的引用变量。”
      
     
      

  7.   

    很好的问题
    当初就曾犯过这个错误
    还是看==和equals的区别时才搞懂的
    期待第二个问题
      

  8.   

    to Schlemiel(维特根斯坦的扇子)
    楼主期望初学者弄懂的事就是:java语言中,对象传值传的是引用,而不是对象本身。这个基本概念涉及到到很多问题,例如“为什么一个对象声明为final却还可以改变”等等。个人认为这是个极重要的概念。
      

  9.   

    to alienbat(亡灵法师):
    我还是觉得没啥用。有错没错,写几个单元测试一测不就知道了吗?
      

  10.   

    源码:
    package csdn;public class Test3{
    public void foo(){
    String s1="s1";

    String s2=s1;

    String s3=new String("s3");
    }
    }字节码:
    public class csdn.Test3 extends java.lang.Object{
    public csdn.Test3();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   returnpublic void foo();
      Code:
       0:   ldc     #2; //String s1
       2:   astore_1
       3:   aload_1
       4:   astore_2
       5:   new     #3; //class String
       8:   dup
       9:   ldc     #4; //String s3
       11:  invokespecial   #5; //Method java/lang/String."<init>":(Ljava/lang/Strin
    g;)V
       14:  astore_3
       15:  return}foo()方法被调用时的方法桢的结构:分三部分 ,局部变量数组,桢数据区,操作数栈
    每个方法的局部变量数组的大小
      以及
    操作数栈的大小在编译时就已经确定了,
    你在java源码中声明的每一个局部变量都会对应局部变量数组中的一项(也有可能多个对应一项),
    实例方法的局部变量数组的第0项总是存放this
    +-----------+ <----
    |   this    |  0
    +-----------+
    |   s1      |  1
    +-----------+     local variables 局部变量数组
    |   s2      |  2
    +-----------+
    |   s3      |  3
    +-----------+ <----
    |           |
    |           |     frame data area 桢数据区
    |           |
    +-----------+ <----
    |           |
    +-----------+
    |           |     op stack 操作数栈
    +-----------+
    |           |
    +-----------+ <----分析每一条语句:
    String s1="s1";
    ===>
         0:   ldc     #2; //String s1    //从常量池中取得字符串常量"s1"并压入操作数栈
                                         //(这个字符串常量在这个类载入并解析时就已经放入到了intern string table中了)
         2:   astore_1                   //从操作数栈弹出一项并保存到局部变量[1]中
         
    String s2=s1;
    ===>     
        3:   aload_1            //把局部变量[1]的内容压入操作数栈
        4:   astore_2           //从操作数栈弹出一项并保存到局部变量[2]中
        
    String s3=new String("s3");
    ===>
        5:   new     #3; //class String            //为一个String对象分配内存,并把它的地址压入操作数栈
        8:   dup                                   //复制操作数栈顶端的元素,并把它压入操作数栈
        9:   ldc     #4; //String s3               //从常量池中取得字符串常量"s3"并压入操作数栈
        11:  invokespecial   #5; //Method java/lang/String."<init>":(Ljava/lang/String;)V
                                                   //取得操作数栈顶的二项,并调用String类的构造函数
        14:  astore_3                              //从操作数栈弹出一项并保存到局部变量[3]中
      

  11.   

    请问Schlemiel(维特根斯坦的扇子),是:
    1. 你认为这个问题没什么意义
    还是
    2. 你认为我没有把这个问题的重要意义讲清楚。
      

  12.   

    to Schlemiel(维特根斯坦的扇子)
    单元测试是应该的,但是事先就排除错误总归比事后发现错误再改正要保险些。
      

  13.   

    to alienbat(亡灵法师):
    例如“为什么一个对象声明为final却还可以改变”等等。能否详细解释一下?to zcjl(【to be forgotten..】) :
    还是看==和equals的区别时才搞懂的也能否具体说说?学习,强烈学习!
    盼望高手讲解!
      

  14.   

    to satangf(好好学习,天天向上!) 如果不介意,我可以解释一下,严格来说,是把对象的一个引用声明为final,
    这样就好理解了,这个引用的值不能改变,也就是只能指向第一次赋给他的对象,
    但是它指向的对象的内容是可以改变的。举个例子,
    final StringBuffer sb=new StringBuffer("123");
    你可以改变对象的内容
    sb.append("456");
    但是你不能改变引用的值
    StringBuffer sb1=new StringBuffer("abc");
    sb=sb1;//这句出错。
      

  15.   

    至于第二个问题参照alienbat (亡灵法师) 的每个初学者都应该搞懂的问题(2)http://expert.csdn.net/Expert/topic/2868/2868492.xml?temp=.1649134
      

  16.   

    怎么没人研究下我提的这个问题呢?难道是怕...我豁出去了,抛块砖吧String s1 = "This is cool!"; // 生成一个字符串对象[OBJ_1],将其引用赋值给s1
    String s2 = "This is cool!"; // 将同样的对象[OBJ_1]的引用赋值给s2
    String s3 = new String("This is cool!"); // 新建一个字符串对象[OBJ_2],其引用赋值给s3;
    s1 = s2; // 将s2保存的[OBJ_1]的引用赋值给s1,没有实际效果
    s3 = "This is cool!"; // 将[OBJ_1]的引用赋值给s3,s3原先引用的[OBJ_2]不再被引用这样的代码共有产生2个String实例,有1对象可以被GC。
    To Schlemiel(维特根斯坦的扇子):这些基本问题搞清楚了当然有用啦,像上面很多人已经提到的by-reference还是by-value的问题,搞不清楚的话可能有些bug很难找;还有就是如果搞不清String s = new String("YES");和String s = "YES";的区别,容易造成new String()的滥用导致程序变慢。//关于by-reference和by-value,说法还不是很统一,有人说参数传递本来就都是by-value的,因为确实我们用来代表和操作对象的变量其实是对象的引用,这个引用和对象本身是不同的。推荐大家看两本好书:Effective Java和Practical Java,很多初学者搞不清楚的问题,还有很多我们平时编码不大注意的问题都提到了。
      

  17.   

    String s = "Hello world!";
    String string = s;
    ------------------------------
    真得很头疼,请问楼主这个过程内存是怎么分配的?
      

  18.   

    to 大胃:
    “还有就是如果搞不清String s = new String("YES");和String s = "YES";的区别,容易造成new String()的滥用导致程序变慢。”
    会变多慢?哪怕你new了一万个多余的String,会比一次数据库操作或者RMI慢吗?我之所以一直说这个问题没意义,就是这个意思。
      

  19.   

    初学者应该在家老老实实的啃书,然后写程序试验单靠CSDN上这只言片语来学习,很容易一瓶子不满半瓶子咣当还是踏实点好我去啃书了……btw:看来楼主是个热心人,感激……
      

  20.   

    To Schlemiel(维特根斯坦的扇子):呵呵。也许你是对的,可能我从很早以前做C/C++的时候就养成一个习惯,要节约资源,放在现在的硬件平台和较新的JVM上恐怕是不那么重要了,那么如果开发J2ME的东西,还能任由其new么?并不是所有的时候都会用到数据库和RMI,如果用到了,就更应该注意节约。我觉得这个习惯始终是好的,如果能不费多大力气就节省了很多资源,何乐而不为呢?把这个"重用"的思想推而广之,举一个极端点的例子,如果把一个大的类放到了循环中间来new,比如Calendar,而不是在循环外new了然后在循环中修改和使用,假定会循环上百次甚至上千次的话,你会发现代码速度的差异有好几十倍。"To new or not to new? That is the question." - Seanspeare :)To all:我可能也没有很好的表达我的意思。我觉得Java的简洁和美丽让不少人忽略了必要的节俭,如果不加控制,等做出一个大项目,恐怕不管JVM怎么先进,怎么优化,怎么JIT,你还是会抱怨Java太慢吧?我希望初学者从一开始就重视这个问题,养成好的习惯,对今后的开发很有帮助的。Java毕竟不是OTC拿来就可以吃,要懂得它的配方才是上策。
      

  21.   

    to satangf(好好学习,天天向上!)
    final关键字的问题我们很快会在后继的帖子里讨论的。这个问题和本系列的第二个问题也有关系。
      

  22.   

    我觉得Java的简洁和美丽让不少人忽略了必要的节俭,如果不加控制,等做出一个大项目,恐怕不管JVM怎么先进,怎么优化,怎么JIT,你还是会抱怨Java太慢吧?我希望初学者从一开始就重视这个问题,养成好的习惯,对今后的开发很有帮助的。
    同意,虽然我目前写的程序就是一团糟
    :(
      

  23.   

    呵呵,很基本的概念,栈和堆,引用和对象。进一步说说数组的问题,如下:
    String[] s = new String[5];
    当执行这一句时,在堆里开一个String数组的对象,引用为s, 这个s是在栈的。但s指向的对象是一个含有5个指向String对象的引用的对象,这些引用依次为s[0],s[1],s[2],s[3],s[4]注意它们可不在栈里,而是在数组对象的堆里。
    文字说的比较饶口,图示就明了了:    Stack                 Heap
      __________            _________
     |__________|     ---> |__s[0]___|--
     |__________|    |     |__s[1]___|  |
     |__________|    |     |__s[2]___|  |--堆中String数组对象
     |__________|    |     |__s[3]___|  |
     |_____s____|-----   --|__s[4]___|--
                        |  |_________|
                        |       :
                        |       :
                        |   _________
                         ->|__null___|--
                           |_________|  |
                           |__null___|  |---(堆中的String对象,由s[i]分别指向,不
                           |__null___|  |     一定是连续空间也不一定按s[i]的顺序。
                           |__null___|  |
                           |__null___|--