【问题标题】:Confusion in declaring String Objects [duplicate]声明字符串对象时的困惑[重复]
【发布时间】:2013-08-12 21:33:09
【问题描述】:

如果我将字符串声明为

String test=new String("testing");

String test1="testing1"

由于 String 是 JAVA 中的一个类,test1 如何在不使用 new Operator 的情况下成为 String 对象。此外,当使用 new Operator 时,会为 new String("testing") 分配内存,所以在 test1 的情况下如何分配的内存? 另外,当字符串被实习时,如果两个字符串具有相同的值,那么字符串在字符串实习池中存储一次的引用是什么?

【问题讨论】:

    标签: java string memory


    【解决方案1】:

    使用时

    String test1="testing1"
    

    那么这意味着您只存储每个不同字符串值的一个副本

    但是

    String test=new String("testing");
    

    给你一个新的字符串对象。

    【讨论】:

      【解决方案2】:

      考虑你的第二个任务是:

      String1 test1 = System.getenv("PATH");
      

      在这里,test1 很可能也是对 String 对象的引用,而不使用 new()。 您可以将现有对象的引用分配给新变量。 那么问题出在哪里?

      问题是,你不能使用像“test1 is a String object”这样草率的措辞。它不是。它是对 String 对象或 null 的引用。就是这样。

      【讨论】:

        【解决方案3】:

        Java 为无需使用new 调用构造函数而创建的字符串提供单独的内存。每次创建这样的字符串时,Java 都会检查该字符串是否已经在此内存中。如果是,则 Java 设置对新字符串的相同引用,直到其中一个发生更改。

        当您使用new 使用构造函数创建字符串时,它的行为与Java 中的普通对象一样。

        看看这个例子:

        String s1 = "Test";
        String s2 = "Test";
        

        当您将此字符串与== 运算符进行比较时,它将返回true。 s1.equals(s2) 也会返回 true。

        如果您使用这样的构造函数创建 String 对象,它看起来会有所不同:

        String s1 = new String("Test");
        String s2 = new String("Test");
        

        当您现在将此字符串与 == 运算符进行比较时,它将返回 false,因为此字符串的引用现在不同(您创建了 2 个唯一的字符串对象)。 但是如果您使用s1.equals(s2),它将按预期返回true。

        【讨论】:

        • 那么是不是只有 String 的特殊情况,我们可以在不使用 new Operator 的情况下声明一个 String 对象?
        【解决方案4】:

        让我们首先考虑这个String test=new String("testing");

        • 它在堆中创建一个字符串对象。没有在字符串池中检查该字符串是否存在于池中。

        现在这个String test1="testing1"

        • 它在字符串池中而不是在堆中创建一个字符串对象。在创建之前检查这个字符串是否已经存在于池中。如果是,则返回它的引用,否则在池中创建一个新的字符串,它的引用是返回。基本上这是一个String Literal,它被放入Constant pool中用于内存优化和可重用性。

        intern(): 当你使用 new() 构造一个对象并在该对象上调用 intern() 时使用它,然后首先在 Stirng 池中进行检查,如果该 String 已经存在那里否,如果是则直接使用

        【讨论】:

        • 请注意,new String("testing") 中的字符串 "testing" 将被保留。
        • @SotiriosDelimanolis 正好 10 倍的信息。为此,我们需要做类似这样的事情 new String("testing").intern(); .
        • 那么是不是只有 String 的特殊情况,我们可以在不使用 new Operator 的情况下声明一个 String 对象?
        • 对于所有 Wrapper Classes,您也​​可以在不使用 new 的情况下创建对象,比如 Integer x=4 也可以。
        • @MarkoTopolnik 我猜我说的事情令人困惑。我的意思是 String 构造函数调用中的 String 文字将被放入池中。对该构造函数调用返回的引用调用intern() 将返回与直接字符串文字分配的引用相同的引用。在这个问题中,如果我们在两次分配之后执行test1 == test.intern(),则测试将产生true
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-02-25
        • 1970-01-01
        • 1970-01-01
        • 2021-01-27
        • 1970-01-01
        • 1970-01-01
        • 2018-01-23
        相关资源
        最近更新 更多