[英]Parameters passing in Java
我在一个类中有一个Long对象,给它一个值,然后将其传递给另一个类的构造函数,在该构造函数中对其进行更改。 为什么更改在第一个对象中不可见?
编码:
public class ClassA {
private Long t;
public ClassA() {
t = new Long(10);
System.out.println(t); // prints 10
new ClassB(t); // it is modified (see ClassB)
System.out.println(t); // prints 10 again
}
public static void main(String[] args) {
new ClassA();
}
}
class ClassB {
private Long p;
public ClassB(Long p) {
this.p = p;
this.p = this.p + 1;
System.out.println(this.p); // prints 11
}
}
输出为:10 11 10 Long变量在ClassA中初始化。 然后,将其传递给ClassB,对其进行修改,并且显然在第一堂课中看不到更改。 为什么?
这是因为Long
类是不可变的。 创建实例后,就永远无法更改。
在这一行:
this.p = this.p + 1;
您正在做的是创建一个新的 Long
对象。 不可变类的其他示例包括原始数字类型( Byte
, Short
等)和String
所有“包装”类。
无济于事的是,它使+
运算符不直观。 真正没有帮助的是,该语言允许在所有这些不可变的类上使用+
。
上一行发生的情况可以写成(尽管我怀疑字节码中发生的情况有所不同):
long tmp = this.p.longValue();
tmp += 1;
this.p = new Long(tmp);
您还可以通过在B
类中将p
标记为final
来验证不变性,这意味着引用 p
永远不会改变; 由于您尝试修改引用p
this.p = this.p + 1
会引发编译错误。
这行this.p = this.p + 1;
不会修改p,而是通过将两个值p
和1
相加来创建一个新的Long
,然后将this.p
设置为对此新Long
的引用。 类的对象Long
没有突变的方法,使他们能够永远不会改变(B类中this.p
没有改变, this.p
成为了一个新的龙的引用)
所以行为实际上是
this.p=p;
Long newLong=this.p + 1;
this.p=newLong;
你在想的是
this.p=p
this.p.imaginaryAddLocal(1);
这会影响原始的p,但是当然不存在这种方法imaginaryAllLocal
,因为Long类的对象是不可变的
首先, Long
是不可变的。 这意味着您无法更改在构造函数中设置的值(请注意,没有set
方法)。
当你做
this.p = this.p + 1;
Java。
1)自动将this.p
转换为其长值(原始)
2)算术运算
3)将结果自动转换回新的不同的Long并将引用分配给this.p
t
一直一直指向原始的Long
对象。
在Java中,您可以通过对象的属性(不建议使用,应将它们设置为private
)或其方法来修改对象。 +
(或其他运算符)将永远不会更改对象状态(尽管可能会创建一个新的对象状态,仅在myString1 + myString2
情况下)
1-您只是在修改B类的p成员
2-Java中的所有内容都按值(而不是引用)传递
Long
类是不可变的,因此您不能通过在调用的函数中对其进行修改来传回该值。 在您的ClassB
,将创建一个副本,并且原始值永远不会更改。
如果希望呼叫者看到更改的值,则必须将其作为返回值传递回去。
其他原始包装器和String也是如此。
因为Java使用传递引用。 这意味着它将传递变量的副本 ,而不是对“原始”变量的引用。
例如,在C ++中,您可以执行以下操作:
void change_var(int &x)
{
x = 2;
}
int x = 10;
change_var(x);
std::cout << x << std::endl;
由于将传递对变量x
的引用,而不是副本,因此将打印2
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.