黑马程序员技术交流社区

标题: java基础问题 [打印本页]

作者: 仵先进    时间: 2012-2-18 09:20
标题: java基础问题
static int a=0;
  static int b=0;
  static int []c={0};
  public static void main(String[] args) {
go(b,c);
System.out.println(a+"  "+b+"  "+c[0]);
}
  public static void go(int b,int[]c){
a=1;
b=1;
c[0]=1;
  }
为什么a变成1 b不变,c变为1呢???
作者: 黄锦成    时间: 2012-2-18 09:41
a是全局变量,你在一个方法中变为1,另外一个方法获取它的值,当然为1。你在go中定义了一个局部变量b,调用方法时将全局变量b传入go方法,意思是拷贝一个份全局变量b赋值给局部变量b,此时你改变局部变量b,跟全局变量b是没有关系的。
c是引用类型,c也是全局变量,你在go方法改变了,在其他地方访问也一样。

这题主要考:值类型和引用类型的区别
作者: 戚雪晖    时间: 2012-2-18 09:48
看你的go方法:
俩参数,只有有一个b 一个c
1.方法内调用的a就是全局变量的a,因此a=1直接改变的是全局变量的a的值,所以a=1;
2.在调用方法时候,你写成go(b,c):这个b是全局变量的b,他是一个基本数据类型,因此,传入的是b的值,所以进一步可以写成go(0,c),而方法里面的b是你在函数参数里定义的,他俩不是一个b,根据作用域,函数里的b是参数的b,因此b=1是改变的参数b的值,跟全局变量的b值无关,所以输出的是b=0。当然如果你想要改变全局的b变量,由于全局的b是静态的,所以你可以把b=1写成:类名.b=1,这样的话输出的就是b=1;
3.go(int b,int[]c),当然这个c也是局部的c,跟全局的c不是同一个。但是你调用函数时候,其实是这样的go(全局的b的值,全局的c的值),而这个全局的c是引用数据类型,因此你把全局的c的地址值赋给了局部的c,所以全局的c和局部c的值指向了同一个对象,在函数内你改变了同一个对象的值:c[0]=1,因此打印结果为c[0]=1。
真难解释。。。。希望抛砖引玉,楼下有更简洁的解释方式。。。
作者: 李晓俊老师    时间: 2012-2-18 10:06
看见你这蛋疼的写法,哥当时就震惊了!第一次见这样写的,,主函数上面写成员变量,虽然没有语法错误,但是跟见非洲人是一样的感觉.
不要忘了,函数括号里面的参数也是局部变量啊,,你go函数里这样写和 int b = 1,是一个道理,你又创建了一个b..当方法调用结束后,
局部变量的生命周期也结束,所以你在go里面的变量b已经挂了,被栈内存释放了..而这时在主函数中输出的b就是那个成员变量b了.
那么为什么c数组的0角标元素没有也变化了呢?不要忘了,数组是引用数据类型,c[]这个数组实体是存在于堆内存中的,所以呢,当方法
调用结束后,它没有被释放,这样你就在go方法中改变了它的0角标元素的值........"O了吧,必须O!"哈哈,这是引用老毕的经典语录啊!
毕老师真牛逼啊,,,人才!强烈推荐看他的视频,那是激情洋溢,热情膨胀,翻江倒海,酣畅淋漓.................
作者: 邱纲    时间: 2012-2-18 10:53
你应该对变量的作用范围不是很清楚,变量分为成员变量和局部变量,它们俩的作用范围不一样的
局部变量:作用域是在本函数范围内。通俗一点说,局部变量只能在定义它的函数内部使用,而不能在其它函数内使用这个变量。
成员变量:作用域是从定义变量的位置开始到本源文件结束。这样成员变量可以让很多函数都使用它。
对于你出现的这种情况是因为:a=1, 是调用了你定义的成员变量static int a = 0;再重新赋值,这样a就等于1
为什么b不等于1呢,因为go(int b,int[]c);b=1是在为go(int b,int[]c)中的b赋值呢,你在main方法中调用的b又是成员变量b,所以显示出来的b肯定是0了
至于c[0]为什么等于1,我也同意上述所说,数组是引用类型,存放在堆内存中,还没有被释放掉,这时调用c[0]肯定还是等于1的,但是成员的属性c[0]没有被赋值。
作者: 花开~的季节    时间: 2012-2-18 11:26
a 是全局,所以a=1
b从全局转到局部,改变的只是局部,在输出的时候依然调用的全局
c[]是引用变量,所以也可以改变




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2