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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

郑明君

注册黑马

  • 黑马币:0

  • 帖子:34

  • 精华:0

© 郑明君 注册黑马   /  2012-7-20 17:13  /  3784 人查看  /  28 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. public class TestPrimitiveTransfer {
  2.     public static void swap (int a, int b){
  3.         int tmp = a;
  4.         a = b;
  5.         b = tmp;
  6.     }
  7.     publicstatic void main(String[] args){
  8.         int a = 6;
  9.         int b = 9;
  10.         swap(a, b);
  11.         System.out.println("交换结束后,参a的值是" + a + ": 参b的值是" + b);
  12.     }
  13. }
复制代码
为什么输出: 参a的值是6;  参b的值是 9

28 个回复

倒序浏览
呵呵。。。这个结果不凌乱撒。。。你了解了函数的参数传递的一些细节就明白其中的原委了。

01.public class TestPrimitiveTransfer {

02.    public static void swap (int a, int b){

03.        int tmp = a;

04.        a = b;

05.        b = tmp;

06.    }

07.    publicstatic void main(String[] args){

08.        int a = 6;

09.        int b = 9;

10.        swap(a, b);

11.        System.out.println("交换结束后,参a的值是" + a + ": 参b的值是" + b);

12.    }

13.}
当函数的传递参数是基本类型的变量时,改函数一结束,改变量也就被释放,也就是说当基本类型的变量作为实参传递,并不能改变主程序中同名局部变量的值。如你的程序中,在swap()函数里面,a和b的值确实进行了交换,in可以在该函数里面加一句System.out.println("交换结束后,参a的值是" + a + ": 参b的值是" + b);进行验证,只是该swap()一结束,a=9,b=6的内存也就随之释放,故此时输出打印的仍然是主函数中同名局部变量的值,即a=6,b=9.
具体情况更多细节你可以查看:http://bbs.itheima.com/forum.php?mod=viewthread&tid=19871
希望对你有所帮助。

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1

查看全部评分

回复 使用道具 举报
程序执行的顺序如下:
   程序从主函数开始,
    main函数进栈,
     里面有了a=6,b=9,
     然后调用swap(int a,int b)方法,
      swap(int a,int b)方法就进栈了。
      调用里面的方法,进行a与b 的交换。
      swap(a,b)执行完就结束了。
     那swap(int a,int b)也出栈了,方法运行的结果并没有被调用。
    所有打印输出的a与b还是main函数里的。
回复 使用道具 举报
public class TestPrimitiveTransfer {

    public static void swap (int a, int b){

        int tmp = a;

        a = b;

        b = tmp;

    }
没有返回值。
正常应该是:
public class TestPrimitiveTransfer {

    public static int  swap (int a, int b){

        int tmp = a;

        a = b;

        b = tmp;

    return a,b;
    }
VOID 没有返回值  只有int,string 等类型才会有返回值。
return.
这个的输出结果是:参a的值是9;  参b的值是 6
回复 使用道具 举报
韩爽 发表于 2012-7-20 17:42
public class TestPrimitiveTransfer {

    public static void swap (int a, int b){

您说的,我一点都看不懂
回复 使用道具 举报
这里的是java的一个特性;和c\c++有点区别;
一方面来说:java中的基本数据,即不是对象的那些数据类型;如int,long,double,float,boolean等;是按照值传递的,不是按应用传递;
也就是说,swap中接受的变量是接受了a,b的值,并不知道是a,b变量;所以这种方法是不可以交换变量的;

如果想深一步了解的话:从内存角度来说:基本类型数据是在常量池中存储的;也就是说在程序加载类的时候就加载在内存中了;不是等main开始执行;
而你的swap函数是在java运行时加载swap时加载的,并且加载到了栈中;也就是说在栈中修改了临时变量a,b。但在常量池中的a,b依旧没有改变;而你输出的时候
栈中的swap的数据和内容帧早已变成垃圾;输出的是常量池中的;自然没有改变;

多了解jvm或者是java内存的分配与运行,有助于理解java程序的运行原理;
我推荐刚看到的一篇文章:深度解析Java内存的原型;http://sd.csdn.net/a/20120629/2806999.html
虽然写的内容格式很乱,但很有借鉴意义
回复 使用道具 举报
夏儒日 发表于 2012-7-20 17:32
呵呵。。。这个结果不凌乱撒。。。你了解了函数的参数传递的一些细节就明白其中的原委了。

01.public clas ...

高见。。
回复 使用道具 举报
陈世涛 发表于 2012-7-20 17:34
程序执行的顺序如下:
   程序从主函数开始,
    main函数进栈,

高见。too
回复 使用道具 举报
韩爽 中级黑马 2012-7-20 17:49:55
9#
郑明君 发表于 2012-7-20 17:46
您说的,我一点都看不懂

那看不懂? 传参必须要有返回值.
回复 使用道具 举报
咋一看楼主写的代码貌似没错,但仔细看看就发现问题了

public class TestPrimitiveTransfer {

    public static void swap (int a, int b){//这个方法能实现交换功能没错,注意方法的返回类型是void空类型,
                   //即使交换成功了,也不能把交换后的值反馈给调用者呀。所以楼主要想实现输出交换后的a,b的值直接在这个交换方法里写一条输出语句即可

        int tmp = a;

        a = b;

        b = tmp;
System.out.println("交换结束后,参a的值是" + a + ": 参b的值是" + b);//就是这个语句

    }

    publicstatic void main(String[] args){

        int a = 6;

        int b = 9;

        swap(a, b);

    // 把这句注释掉看下运行结果   System.out.println("交换结束后,参a的值是" + a + ": 参b的值是" + b);//它输出的只会是a,b原来的值,因为调用的方法并没有把改变后的值反馈给它。

    }

}

结果如下图:

回复 使用道具 举报
梁小波 发表于 2012-7-20 17:46
这里的是java的一个特性;和c\c++有点区别;
一方面来说:java中的基本数据,即不是对象的那些数据类型;如 ...

必须有借鉴意义。恩,,, 一看这手笔,就很老道。。呵呵。谢谢
回复 使用道具 举报
韩爽 发表于 2012-7-20 17:49
那看不懂? 传参必须要有返回值.

不见得把,传参也可以不用有返回值呀,直接void,写一条输出语句,输出交换后的值,然后调用者调用这个方法的时候同样能达到一样的效果呀。
回复 使用道具 举报
本帖最后由 罗京雨 于 2012-7-20 17:57 编辑

public class TestPrimitiveTransfer {
    public static void swap (int a, int b){
        int tmp = a;
        a = b;
        b = tmp; //在这里运行完的数值和主函数一点关系都没有,直接弹栈了
    }
    publicstatic void main(String[] args){
        int a = 6;
        int b = 9;
        swap(a, b);    //这句话是迷惑性的,相当于废话
        System.out.println("交换结束后,参a的值是" + a + ": 参b的值是" + b); //所以输出的还是你定义的a=6,b=9的值。
    }
}

弹栈.JPG (47.04 KB, 下载次数: 34)

弹栈.JPG

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

回复 使用道具 举报
苑占丽 发表于 2012-7-20 17:50
咋一看楼主写的代码貌似没错,但仔细看看就发现问题了

public class TestPrimitiveTransfer {

你搞错我的意图了。要是真想要输出结果达到交换状态,那么我写的代码和你一样。但是我就想写这么个例子,问问底层JVM是怎么实现的。
回复 使用道具 举报
韩爽 发表于 2012-7-20 17:49
那看不懂? 传参必须要有返回值.

也可以没有的。:lol:victory:
回复 使用道具 举报
罗京雨 发表于 2012-7-20 17:55
public class TestPrimitiveTransfer {
    public static void swap (int a, int b){
        int tmp = a ...

恩。。很详细。还有图解,真是个大好人呢~~
回复 使用道具 举报
public class TestPrimitiveTransfer {
    public static void swap (int a, int b){
        int tmp = a;
        a = b;
        b = tmp;
    }
    publicstatic void main(String[] args){
        int a = 6;
        int b = 9;
        swap(a, b);
        System.out.println("交换结束后,参a的值是" + a + ": 参b的值是" + b);
    }
}

由于传的是基本数据类型,所以swap()函数中参与运算的变量丝毫不影响主函数,函数结束相应变量就释放
如果传入一个引用数据类型就不同了,比如说数组

public class TestPrimitiveTransfer {
public static void swap(int[] arr, int a, int b) {
  int tmp = arr[a];
  arr[a] = arr[b];
  arr[b] = tmp;
}
public static void main(String[] args) {
  int arr[] = { 6, 9 };
  int a = 0;
  int b = 1;
  System.out.println("开始数组的值:");
  for (int i = 0; i < arr.length; i++) {
   System.out.println(arr[i]);
  }
  swap(arr, a, b);
  System.out.println("交换结束后的值:");
  for (int i = 0; i < arr.length; i++) {
   System.out.println(arr[i]);
  }
}
}

结果:
开始数组的值:
6
9
交换结束后的值:
9
6
回复 使用道具 举报
陌花╮有意、 发表于 2012-7-20 18:12
public class TestPrimitiveTransfer {
    public static void swap (int a, int b){
        int tmp = a ...

为什么说引用类型的就不一定了呢。那是一定呢。还是一定不呢? 但是你给的例子证明,引用类型的变量一定被改变了,是吗?
回复 使用道具 举报
本帖最后由 苑占丽 于 2012-7-20 18:26 编辑
郑明君 发表于 2012-7-20 18:00
你搞错我的意图了。要是真想要输出结果达到交换状态,那么我写的代码和你一样。但是我就想写这么个例子, ...

那好吧,看到楼上的好多回复,我还想再补充一点:
代码稍微改动了一点
public class TestP {

    public  static int swap (int a, int b){

        int tmp = a;

        a = b;

        b = tmp;
//        System.out.println("交换结束后,参a的值是" + a + ": 参b的值是" + b);
     return a;//不能同时 return a,b;会报错,只能有一个返回值,此时a的值为9
    }

    public static void main(String[] args){

        int a = 6;

        int b = 9;

        swap(a, b);

//        System.out.println("交换结束后,参a的值是" + a + ": 参b的值是" + b);
        System.out.println("交换后a的值变为"+swap(a, b));
    }

}
运行结果是这样的:

写这个,我就是想说明你赞同的楼上的这句话"但在常量池中的a,b依旧没有改变;而你输出的时候
栈中的swap的数据和内容帧早已变成垃圾;输出的是常量池中的;自然没有改变
;"我有异议
在主函数里 swap(a, b);这句话确实是改变了a,b的值,又怎回是没用的呢?通过返回值可以看到,而主函数输出swap的数据的和内容的时候,确实可以的呀
回复 使用道具 举报
郑明君 发表于 2012-7-20 18:19
为什么说引用类型的就不一定了呢。那是一定呢。还是一定不呢? 但是你给的例子证明,引用类型的变量一定 ...

值传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参 数的值。
引用传递:也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,方法执行中形式参数值的改变将会影响实际参数的值。
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马