对java中的内存感到困惑

时间:2013-10-19 06:02:22

标签: 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";
        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);
}
}

5 个答案:

答案 0 :(得分:2)

首先,java中的所有内容都是按值传递的。甚至引用也都是通过值传递的。

您已创建新的string字面值,但未在方法func()中返回该字面值。

您正在修改传递的参数而不是原始string,因此您无法看到更改。

你可能需要这个,

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
 } 

编辑评论:

不,两者都不相同。 String的两种方式之间存在很大差异,特别是在记忆方面。

阅读

<强> EDIT2:

在第一种情况下,您在func方法中创建了一个新的字符串文字,但在这里您要修改引用。

你的疑问澄清你何时完成

  static void func(Thing t){
     t = new Thing(); //as like previous example
     t.x = 90;       // points to new one. Not the original.

    }

现在检查结果。

答案 1 :(得分:0)

如上所述here

  

Java按值传递所有内容,而不是通过引用传递 - 确保您   记得那个。当我们说出一切时,我们就意味着一切 -   对象,数组(Java中的对象),原始类型(如   整数和浮点数等等 - 这些都是用Java中的值传递的。什么   传递值和传递参考之间的区别是什么?什么时候   将参数(甚至多个参数)传递给方法Java   将在原件内创建一个或多个值的副本   变量并将其作为参数传递给方法 - 这就是原因   它被称为按值传递。传递值的关键是   方法不会收到正在传递的实际变量 - 但是   只是存储在变量中的值的副本。

答案 2 :(得分:0)

它与不变性无关。这些都是关于如何传递参数和变量范围的。

这是你的函数调用

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);

仍然指向“旧”。为x分配了一个新的String对象,该对象是方法func的本地对象。因此,它仍然打印“旧”。

答案 3 :(得分:0)

  

所以,如果我声明一个字符串并将其传递给我改变的函数   字符串的值,为什么原始字符串不会改变?

重要的是要知道你不能声明一个值为字符串的变量 - 字符串(它们是对象)不是Java中的值。 y引用(指向对象的指针)。 Java中唯一的类型是基本类型和引用类型。类型String引用类型

因此,您传递y,一个引用(指向对象的指针)。在函数内部,x同样是一个引用(指向对象的指针)。更改引用的值(例如,将(=)分配给x)从不会对它可能指向的对象产生任何影响。

.运算符允许您访问引用所指向的对象的字段。分配.访问的结果会更改引用所指向的对象,而不是引用本身。这些是非常不同的东西。

答案 4 :(得分:-1)

在Java对象中,字符串的处理方式不同,字符串在JAVA中保持不变。

在你的例子中更清楚:

让我们假设,String y指向内存位置2000,字符串x指向内存 location 2001,所以你得到了相同的旧价值..

如果是对象请参考我的示例:

http://javaambition.blogspot.kr/2013/08/java-pass-by-value.html