关于对象参数是传值还是传引用的问题。
y是数据类型对象,把对象传递给 testForInteger(Integer x)方法,方法体里面累加1传回去。
为什么y值没变化,对象不是应该传引用吗?只有基本数据类型才传值。
public
class
main1 {
public
static
void
main(String[] args) {
Integer y=
1
;
testInteger test =
new
testInteger();
test.testForInteger(y);
System.out.println(y);
}
}
class
testInteger{
public
Integer testForInteger(Integer x) {
return
++x;
}
}
++x时,x变成基本类型int了。
对象不存在++操作
https://www.journaldev.com/3884/java-is-pass-by-value-and-not-pass-by-reference
可以看下这个帖子,可能会颠覆你的认知,java永远都是值传递。。。跟老师讲(对象引用传递,基本类型值传递)的不一样。理解就好,没必要较真
java只有值传值,当方法参数为引用类型时,传递的是实参的值也就是实际对象的地址
你好。但是数组又怎么解释?请看以下代码,数组传过去就变改变了,然而Integer对象传过去就没被改变。
public
class
test {
public
static
void
main(String[] args) {
Integer x =
1
;
testForInteger(x);
System.out.println(x);
int
[] testarray = {
1
,
1
,
1
,
1
,
1
,
1
};
changearray(testarray);
for
(
int
i =
0
; i<testarray.length; i++) {
System.out.println(testarray[i]);
}
}
public
static
void
testForInteger(Integer x) {
x.valueOf(
3
);
}
public
static
void
changearray(
int
[] array) {
for
(
int
i =
0
; i<array.length; i++) {
array[i] =
20
;
}
}
}
这是基本类型包装类的特殊性,String也一样,不提供通过引用变量来修改属性的方法,一旦修改引用变量就直接变成指向另一个对象,简单的说就是没法通过引用变量来修改对象的内容,只能通过改变引用变量的指向使其引用新的对象而达到对象内容变更的目的。
比如
Integer n = 5;
Integer m = n;
System.out.println(n==m); //true,说明m和n引用同一个对象
m++; //没法通过修改属性来修改对象的内容,修改对象的内容只能修改m的指向,m不再引用原来的对象,而是引用了一个新的对象
System.out.println(n==m); //false,说明m和n引用不同的对象
可见和String相似
String s1 = "abc";
String s2 = s1;
System.out.println(s1==s2); //true,说明s1和s2引用同一个对象
s2 += "123"; //没法通过修改属性来修改对象的内容,也就是没法在原来对象字符串的末尾追加“123”,只能s2引用另一个新的对象
System.out.println(s1==s2); //false,说明s1和s2引用不同的对象
而对于数组对象来说,可以不修改引用变量的指向而只修改数组的元素(相当于修改对象的属性),从而达到不改变引用变量的指向就能修改原来对象的内容
int[] a = {1,2,3};
int[] b = a;
System.out.println(a==b); //true,说明a和b引用同一个对象
b[0] = 4;
System.out.println(a==b); //true,说明修改数组的元素,并不改变b的指向,b还是引用原来的对象
System.out.println(a[0]); //因为a和b引用同一个对象,所以通过b修改对象属性,通过a也能看到变换
b = new int[1,2,3}; //注意这里的区别,这里不是修改对象的属性,而是修改b指向了另一个对象
System.out.println(a==b); //false,这就是修改引用对象的属性和修改引用的指向的区别
所以,方法内的修改对象的内容,能不能影响到方法外的引用变量lrc歌词下载,就看方法内修改对象是通过修改引用对象的属性的方式还是通过修改引用的指向的方式来修改的,如果是前者,则影响方法外的引用变量,是后者,则不影响。
首先你这个 x.valueOf(3);这个操作,用法就不对valueOf是静态方法,它不会影响你形参x(传递进方法中的x)和实参x(main方法中的x),也就是你在方法内输出x,他也是1
public
static
void
testForInteger(Integer x) {
x.valueOf(
3
);
// 等价于Integer.valueOf(3); 跟x完全没得关系
System.out.println(x);
}
针对数组画个图解释一下子
如图所示,在调用方法changearray时,将testarray的值0x001 传递给方法changearray的形参array,那么array=0x001,
在后续你对array的操作时,实际上时操作了堆中的内容,操作完后堆中的数组变成了{20,20,20 。。。}, 此时array = 0x001(也就是堆中的{20,20,20。}数组), 那么testarray还是=0x001,也就是你打印的20
按引用传递的意思是你传的是这个变量本身,而不是变量的拷贝值
比如
int[] a={a,b,c}
调用一个方法
void f(int[] a)
{
a=null;
}
当你执行完f(a)之后,在打印数组a的值,发现他并不是空值
按引用传递并不是指你的方法参数是一个引用变量还是一个值,而是相对于传进去的变量,是这个变量的引用还是这个变量的值。
数组变量名本身就是一个引用,而传参时传的是这个引用的值(一个内存地址)
Java的方法参数只是传值,引用作为参数使用时,会给函数内引用的值的COPY,所以在函数内交换俩个引用参数是没意义的,因为函数只交换参数的COPY值,但在函数内改变一个引用参数的属性是有意义的,因为引用参数的COPY所引用的对象时和引用参数是同一个对象。
C++指针作为参数给函数使用,实际上就是它所指的地址在被函数操作,所以函数内使用指针参数的操作都将直接作用到指针所指向的地址(变量,对象,函数等)