字符串和内存

时间:2011-06-27 06:34:08

标签: java string

class A {



  public void someMethod() {
         String var = "Abhi";
         var = "Abhishek";
  }
}

var变量会将Abhi和Abhishek存储在不同的内存位置还是Abhishek会覆盖Abhi

如果我使用这个表达式String var= new String();,那么呢?

6 个答案:

答案 0 :(得分:8)

鉴于此方法:

public void someMethod() {
    String var = "Abhi";
    var = "Abhishek";
}

在这个例子中有3个相关的东西:

  • 有一个名为var变量。此变量存储在堆栈中(因为它是局部变量)并且可以保存对某个对象的引用。
  • 内容为String Abhi对象:这是var在声明后立即引用的第一件事。
  • 内容为String Abhishek对象var被修改为在第二行引用此对象,其中提到var

因此,就内存而言:两个 String个对象存储在不同的空间中,彼此无关。 var但是,只占用同一个地方(在foo的单次调用期间)。因此,对Abhi引用会被Abhishek 的引用覆盖。

如果在该方法的末尾添加行var= new String();,那么该行将执行两项操作:

  1. 创建一个代表空String
  2. 的新String对象
  3. 将对该新String对象的引用分配给变量var
  4. 请注意,几乎没有理由使用String构造函数,因为""(几乎)具有完全相同的效果。

答案 1 :(得分:1)

它们可能是不同的记忆值。

当然可以想象一些高级JVM可以实现这个功能,但它可能不太可能,而且我从未听说过在真正的编译器中使用过这样的优化;特别是考虑到这是一个非常低的支付优化(你节省了一些本来用于表示较短字符串的字节),这需要一些非常特殊的条件才能工作(即你有一个字符串常量,这是另一个的前缀) )。

编辑:根据Jesper的评论纠正了答案。

答案 2 :(得分:0)

  

var变量会将Abhi和Abhishek存储在不同的内存位置,还是Abhishek会覆盖Abhi ??

都不是。此代码将无法编译,因为您声明了两个具有相同名称var的变量。

如果我们看一下:

class A {
    public void someMethod {
        String var = "Abhi";
        var = "Abhishek";
    }
}

var的第二个作业会使var引用不同的String对象。

请注意,在Java中,变量是引用到对象 - 它们不直接表示对象(如在C ++中)。

答案 3 :(得分:0)

您的新字符串将被放入内存中的新位置,因为它将是一个新对象,但不要担心... java中有垃圾收集机制,因此您的旧对象内存将在此之后立即恢复,因为那里将不会为您的旧字符串对象提供参考...

答案 4 :(得分:0)

另外,值得一提的是Java中String对象的不变性。具体来说,在您的示例中,即使您覆盖了变量var引用的String的引用,数据本身也不会被“覆盖”。

答案 5 :(得分:-1)

在Java中,您无法定义“var”两次。它不会简单地创建一个新的内存位置,并在那里抛出一个新的“var”实例。我们的第一步必须修复您的代码。相反,您的代码将如下所示:

  String var = "Abhi";
  var = "Abhishek";

因此,回答你的第一个问题,是的。 “Abhishek”将覆盖“Abhi”。

如果您使用

String var= new String();

表示您创建类String的新实例,并将其分配给var。 Var成为一个新的,空的(我相信),字符串。