A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

public class Test {
public static void main(String[] args) {
  int[] a={2,5,3,9,8,1,6};
  int k = 1;
  String s = "as";
  
  Test test = new Test();
  
  test.print(a,k,s);
  
  test.selectionSort(a,k,s);
  
  test.print(a,k,s);


}

public void selectionSort(int[] b,int k,String s){
  for(int i=0;i<b.length;i++){
   for(int j=i+1;j<b.length;j++){
    if(b[i]>b[j]){
     int temp = b[i];
     b[i] = b[j];
     b[j] = temp;
    }
   }
  }
  
  k = 10;
  s = "asasasasass";
}

public void print(int[] a,int k,String s){
  for(int i=0;i<a.length;i++){
   System.out.print(a[i]);
  }
  System.out.println();
  System.out.println(k);
  System.out.println(s);
}


}
我明白值类型是直接在栈中分配了一个空间,而引用类型是在堆中开辟了一个空间,然后把引用给了变量,但是我不明白的是我上面的代码,会出现这样的结果
2539816
1
as
1235689
1
as
第一行的输出是数组,属于引用类型,变化了,我可以理解;
第二行是int值类型,没有变化,也可以理解;
第三行的string是引用类型,为什么没有跟第一行的引用类型一样变化呢!这是我所不明白的。

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 赞一个!

查看全部评分

9 个回复

倒序浏览
首先你的String s = "as";不是一个引用类型,你没不是String s=new String("as");
这两者是有区别的:
1、String s = "as";他只是一个String类型的普通变量,它的创建方式是先到变量池中去找看是否有一个"as",如果有,就把他赋给s,如果没有就会在变量池中新建一个"as"然后赋给s,所以s并不在堆内存中,而是在变量池中。所以他没有引用某个对象的地址,他就是一个普通的变量。
2、String s=new String("as");  这就不一样了,这是在堆内存中创建一个对象String ,然后把这个对象的地址赋值给s。这才是所谓的引用变量。

靠它来拿最后一个技术分了,现在24了。。。

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 好,给你了

查看全部评分

回复 使用道具 举报
阳永衡 发表于 2012-11-15 13:24
首先你的String s = "as";不是一个引用类型,你没不是String s=new String("as");
这两者是有区别的:
1、S ...

。。。  哥们这可不是讨要的,认认真真地答的,自觉还不错   。。。
回复 使用道具 举报
阳永衡 发表于 2012-11-15 13:24
首先你的String s = "as";不是一个引用类型,你没不是String s=new String("as");
这两者是有区别的:
1、S ...

哥们这可不是讨要的啊!!认认真真答的,自觉还不错!!

点评

知道的,你的回答挺不错的,嘿嘿  发表于 2012-11-16 19:42
回复 使用道具 举报
1:
String s = "as";
它的创建方式是先到变量池中去找看是否有一个"as",如果有,就把他赋给s,如果没有就会在String缓冲池中新建一个"as"然后赋给s,所以s并不在堆内存中,而是在String缓冲池中。
你的第二个 s = "asasasasass";  又在缓冲池中开辟了一个新的空间。
2:String s=new String("as"); 时,是在堆内存中创建空间的。


回复 使用道具 举报
首先更正楼上的答案,String s = "ASD";和String s = new String("ASD");的效果是一样的。这两种方式的区别就是在对内存中开辟地址,和字符串池中取值。一个是编译时,一个是运行时。但是其效果都是一样的,因为看看String类的源码就晓得了,String 类是一个final类。并且内部实现其实是个char[]数组所以方法传递的其实只是s的一个副本,方法修改的也只是副本的值而已。我把你的代码改了改,你再看看结果 发现数组也没有改变。这就说明了一个问题,这个方法传递的其实也是数组的一个副本,但是它们指向了同一个地址。所以方法修改的只是把副本的指向改变了,并没有真正改变数组的值。String内部也是一个char[]数组.所以也可以得出同样的结论。
public class TestProblem1 {
        public static void main(String[] args) {
                int[] a={2,5,3,9,8,1,6};
        int k = 10;
                  String s = "as";
                  TestProblem1 t1 = new TestProblem1();
                  t1.print(a, k, s);
                  t1.selectionSort(a, k, s);
                  t1.print(a, k, s);
        }
        public  void selectionSort(int[] b,int k,String s){
                  b = new int[] {1,2,3,4,5,6};
                  
                  k = 10;
                  s = "assssssssss";
                }

                public  void print(int[] a,int k,String s){
                  for(int i=0;i<a.length;i++){
                   System.out.print(a[i]);
                  }
                  System.out.println();
                  System.out.println(k);
                  System.out.println(s);
                }
}
我先扔出我的结论:
基本类型和基本类型变量被当作参数传递给方法时,是值传递。在方法实体中,无法给原变量重新赋值,也无法改变它的值。
对象和引用型变量被当作参数传递给方法时,是引用传递。在方法实体中,无法给原变量重新赋值,但是可以改变它所指向对象的属性。
回复 使用道具 举报
奚华 中级黑马 2012-11-16 13:14:41
7#
王阳 发表于 2012-11-15 20:18
首先更正楼上的答案,String s = "ASD";和String s = new String("ASD");的效果是一样的。这两种方式的区别 ...

我认为你的说法是错的,java只有值传递。对于基本类型,传入的是基本类型的值,对于引用类型,传入的是被引用对象的地址!

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 赞一个!

查看全部评分

回复 使用道具 举报
奚华 中级黑马 2012-11-16 13:15:50
8#
引用类型传入的对象的地址的值,仍然是值!
回复 使用道具 举报
奚华 中级黑马 2012-11-16 13:16:11
9#
并没有传入对象本身
回复 使用道具 举报
王阳 中级黑马 2012-11-16 19:24:50
10#
xmanxihua 发表于 2012-11-16 13:15
引用类型传入的对象的地址的值,仍然是值!

不好意思,可能我意思没表达清楚,我的意思是引用传递的是副本,他们指向堆内存中同一个对象,(字符串有可能是字符串池),所以方法中改变的是另一个副本指向的堆内存对象。这样说应该严谨多了。谢谢楼上帮我找出错误

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 赞一个!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马