您的位置:首页 > 编程语言 > Java开发

java 值传递 引用传递

2018-03-27 20:20 183 查看
在练习一道关于数组的题时,写了一个方法对于数组内的值进行改变,运行后发现此方法不奏效。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
String a=scan.next();
String b=scan.next();
scan.close();
char [] aa=a.toCharArray();
char [] bb=b.toCharArray();
int count=0;
 
for(int i=0;i<aa.length;i++){
if(aa[i]!=bb[i]){
reverse(aa,i);//因为数组是传递引用,所以只传值过去是不可行的
reverse(aa,i+1);
//reverse(aa[i]);
//reverse(aa[i+1]);

count++;
}
}
System.out.println(count);
}
static void reverse(char a[],int i){
if(a[i]=='*'){
a[i]='o';
}else if(a[i]=='o'){
a[i]='*';
}
}
/*static void reverse(int x){//此方法为错误的方法
if(x=='*'){
x='o';
}else if(x=='o'){
x='*';
}
}*/
}

代码如上
后来发现关系到java中传递的类型,一种是值传递,一种是引用传递。
在java中,不允许程序员选择值传递还是地址传递各个参数,基本类型总是按值传递。对于对象来说,是将对象的引用也就是副本传递给了方法,在方法中只有对对象进行修改才能影响该对象的值,操作对象的引用时是无法影响对象的值的。

重要概念:

1.形参和实参:
形参:定义在方法(函数)上的参数,用来接收传递过来的实参值。
实参:出现在调用方中,可以是常量、变量、表达式和函数,但是必须被赋值。
形参在函数调用完之后在内存中被释放,形参可以接收基本数据类型值和引用:接收值时只是将原变量值复制,而引用则是将引用值(对象在内存中的虚拟首地址)传递过来,可以实现对对象的操作。
2.基本数据类型和引用类型:
基本数据类型是对一些固定存储结构数据类型的定义,是固定长度的;引用类型包括类和对象、数组、接口,引用类型较复杂,方法中创建一个引用时,此时在栈区分配了一个4byte的空间,但是还没有创建数据,当使用new运算或反射等方法创建对象时,此时就在堆区开辟空间创建数据,然后将该对象在堆内存中的虚拟首地址值赋给引用。
据上:值传递涉及的是方法调用中基本数据类型值的传入,形参的改变并不会影响实参的改变。而引用传递是方法调用中引用的传递,并没有涉及到对象。(也有人可能会认为引用传递传递的就是引用中存储的对象堆内存地址值,但是与值传递比较值传递是将值复制一份传递,引用传递并没有复制对象,没有创建新的数据存储空间,堆内存中始终只有一个对象,从这点上看,就可以理解为什么要分为值传递和引用传递了。)然而当该引用类型值可以改变或调用了改变其自身的方法时,形参对实体对象的操作会被保存。也就是说,使用实参再次访问该对象的属性时发生了改变。
需要注意的是,某些value被final修饰的类,如String、Integer等,由于其一旦创建则不可更改,所以对形参值的改变就意味这创建了一个新的对象,而原有对象并没有改变。

例:

 
 str是String类型的引用,i是基本类型变量,ch是数组名,也是数组对象的引用
在chang()方法里,str="test ok",是一个新的对象把首地址放在引用变量str上;
而ch[0]='g';因为传的是数组的引用,而此时ch[0]='g';是对数组元素的操作,能修改源数组的内容;
i是整型值,只是把值copy了一份给方法,在方法的变化是不改变的源i的。
所以结果是:
10
good and gbc
 
仔细观察下实参以及入参有何变化?
change()方法里的入参char[] ch变成--------------char ch;
这次传递的是个char值的单个数组元素,按照上面的解析,此时ch='9';是不影响源数组元素的。
this.i = i+1;这里面等号左边的i是属性i,等号右边的i是局部变量(入参里的i);
此时i+1后赋值给属性的i,自然会改变属性i的值,同时17行,tt.i又是调用属性的i,这次的结果是:
11
good and abc
总结:

值传递:
方法调用时,实际参数把它的值传递给对应的形式参数,函数接收的是原始值的一个copy,此时内存中存在两个相等的基本类型,即实际参数和形式参数后面方法中的操作都是对形参这个值的修改,不影响实际参数的值
引用传递:
也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,函数接收的是原始值的内存地址;
在方法执行中,形参和实参内容相同,指向同一块内存地址,方法执行中[b]对引用的操作将会影响到实际对象[/b]。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: