public class wo{
public static void main (String args[]) throws IOException
{
StringBuffer a = new StringBuffer ("A");
StringBuffer b = new StringBuffer ("B");
operate (a,b);
System.out.println(a+" "+b);
}
static void operate (StringBuffer x, StringBuffer y) {
x.append(y);
y = x;
}
}
输出AB B
为什么?
public static void main (String args[]) throws IOException
{
StringBuffer a = new StringBuffer ("A");
StringBuffer b = new StringBuffer ("B");
operate (a,b);
System.out.println(a+" "+b);
}
static void operate (StringBuffer x, StringBuffer y) {
x.append(y);
y = x;
}
}
输出AB B
为什么?
String m="fsd";
m.concat("b");
System.out.println(m);
输出的还是fsd
我是不是可以这么理解,m.concat("b")相当于重新new了一个string并给它分配了空间
如果是的话,那我上面的 x.append(y);为什么不可以这样理解啊?
有谁知道底层的机制么?
y = x;b的内容没有变引用的问题了
其实问题很简单,只要了解如下基本知识:
1、变量类型
值 变 量:用于代表存储大小确定的值
引用变量:用于代表存储大小不定的值
2、变量存储
栈:分配的存储空间不可改变,在超过作用域后能够自动回收
堆:分配的存储空间可以改变,在超过作用域后需要垃圾回收
值 变 量:只在栈中申请一个与自己值域匹配的空间,用于存放自身的值
引用变量:先在栈中申请一个与 CPU 寻址能力匹配的空间,用于存放一个地址值
再在堆中申请一个存放自身实例的空间,并把这个空间的首地址放入栈中预先申请的空间
变量名:都是程序代码中栈空间的首地址的代表,程序编译时,变量名会被替换为相对于栈首地址的偏移量
3、方法的参数传递
值 传 递:方法的形参申请自己的存储空间,运行时把方法调用时的实参值复制给形参的方式
引用传递:方法的形参不申请自己的存储空间,让方法的形参与实参共享同一存储地址的方式
4、Java的参数传递方式:值传递
对于值参数,把实参值复制给形参,所以值参传递时形参在方法中的改变不影响实参。
对于引用参数,也是把实参值复制给形参,只是这次复制的值是实参的栈空间中存放的值(栈中存了堆中的首地址值),也就是说:实参与形参将共用同一个堆空间。为此:
方法中如果改变了堆空间中的内容,实参能同步改动;
方法中如果改变了形参本身的栈中值(存放了一个新的堆空间首地址值),由于是值传递,实参是不变的本例中:
x.append(y);//把形参y的实例值加到形参x实例值中,改变的是形参x堆空间中的内容,a同步改动
y=x;//把形参x的栈中值复制给形参y,使x、y共用同一堆空间,改变的是形参y栈空间中的内容,b不变
我明白了,感激不尽啊!!!!
package test;public class test {
public static void main(String ... s)
{
int[] arr = {1,2,4,3,5,6};
System.out.println(arr[2] + "," + arr[3]);
/*交换下标为2,3两个数*/
swap(arr,2,3);
System.out.println(arr[2] + "," + arr[3]);
}
public static void swap(int[] arr,int x,int y)
{
int tmp;
tmp = arr[x];
arr[x] = arr[y];
arr[y] = tmp;
}
}