对java中的内存感到困惑
据我所知,java中的对象是通过引用传递的,或者更准确地说,对对象的引用是通过值传递的。那么,如果我声明一个字符串并将其传递到一个函数中,在这个函数中我更改了字符串的值,为什么原始字符串没有更改?例如:对java中的内存感到困惑,java,pointers,memory,pass-by-reference,Java,Pointers,Memory,Pass By Reference,据我所知,java中的对象是通过引用传递的,或者更准确地说,对对象的引用是通过值传递的。那么,如果我声明一个字符串并将其传递到一个函数中,在这个函数中我更改了字符串的值,为什么原始字符串没有更改?例如: class Thing { static void func(String x){ x = "new"; } public static void main(String [] args) { String y = "old"; fu
class Thing
{
static void func(String x){ x = "new"; }
public static void main(String [] args)
{
String y = "old";
func(y);
System.out.print(y);
}
}
为什么y的值仍然是“旧的”
编辑:为什么下面将某物的属性x设置为90
class Thing { int x = 0;
static void func(Thing t){ t.x = 90; }
public static void main(String [] args){
Thing something = null;
something = new Thing();
func(something);
System.out.print(something.x);
}
}
首先,java中的一切都是按值传递的。甚至引用也是按值传递的 您已经创建了一个新的
字符串
literal,并且没有在方法func()
中返回该字符串
您正在修改传递的参数,而不是原始的字符串
,因此无法看到更改
你可能需要这个
public static void main(String [] args)
{
String y = "old";
y= func(y);
System.out.print(y);
}
static String func(String x){
x = "new";
return x
}
编辑评论:
不,它们不一样。两种字符串的方式有很大的不同,特别是在内存方面
阅读
Edit2:
在第一种情况下,您将在func
方法中创建一个新的字符串文本,但在这里您将修改引用
当你完成时,你的怀疑就澄清了
static void func(Thing t){
t = new Thing(); //as like previous example
t.x = 90; // points to new one. Not the original.
}
现在检查结果。如前所述:
Java通过值传递一切,而不是通过引用——请确保
记住这一点。当我们说每件事时,我们意味着每件事——
对象、数组(Java中的对象)、基元类型(如
int和float)等–在Java中,这些都是通过值传递的。什么
传递值和传递引用之间的差异是多少?什么时候
将一个参数(甚至多个参数)传递给一个方法,Java
将在原始文件中创建一个或多个值的副本
变量,并将其作为参数传递给方法,这就是原因
它被称为按值传递。具有传递值的键是
方法将不会接收正在传递的实际变量–但是
只是存储在变量中的值的副本
在Java中,对象和字符串的处理方式不同,字符串在Java中保持不变
要在您的示例中更加清楚,请执行以下操作:
假设字符串y指向内存位置2000,字符串x指向内存
位置2001,所以得到相同的旧值
如果是对象,请参考我的示例:
它与不变性无关。所有这些都是关于如何传递参数和变量的范围
这是您的函数调用
String y = "old"; // The reference y pointing to the string object "old": y ---> "old"
func(y);
当您输入被调用的函数时
static void func(String x){ // x = y which means x now points to "old": x ---> "old"
x = "new"; // x ---> "new": now the local variable x is pointing to a different object. y still points to "old".
} //Scope of x ends here
当我们打印它的时候
System.out.println(y);
y仍然指向“旧”。一个新的字符串对象被分配给了方法func的本地x。因此,它仍然打印“旧”
所以,如果我声明一个字符串并将其传递到一个函数中
字符串的值,为什么原始字符串不更改
需要知道的重要一点是,不能声明值为字符串的变量——字符串(即对象)在Java中不是值<代码>y
是一个引用(指向对象的指针)。Java中唯一的类型是基元类型和引用类型。类型字符串
是引用类型
因此,您正在传递一个引用(指向对象的指针)。在函数内部,x
同样是一个引用(指向对象的指针)。更改引用的值(例如,将(=
)赋值为x
)不会对它可能指向的对象产生任何影响
操作符允许您访问引用指向的对象的字段。分配给
访问的结果会更改引用指向的对象,而不是引用本身。这些都是非常不同的东西。Sklak,把x=“ABC”想象成与x=newstring(“ABC”)相同的东西。为什么下面将Thing的属性x设置为90?(参见有问题的编辑)@SKLAK请检查更新。你们两个例子是不同的。第一种情况是创建一个新字符串,第二种情况是不创建字符串,那么为什么我们能够更改对象的属性呢。例如,假设你有一辆拥有速度和颜色属性的汽车。假设在这个类中有一个静态函数,它将通过的汽车的速度设置为100。如果我在main中创建一个名为carx的汽车,并执行类似setSpeed(carx)的操作,carx.getSpeed()是否会返回100?你不能只在从其他地方复制的答案底部转储一个链接。您需要清楚地引用此内容,以表明这些内容都不是您的原始文字。我在上面已经这样做了。“我们指的是一切——对象、数组(Java中的对象)、基本类型(如int和float)等等——这些都是Java中按值传递的”“对象”在Java中不是值,不能“传递”。