下面这两种说法有什么不同?

String s = "text";

String s = new String("text");

当前回答

String str = new String("hello")

它将检查字符串常量池是否已经包含字符串“hello”? 如果存在,则不会在String常量池中添加条目。如果不存在,它将在String常量池中添加一个条目。

对象将在堆内存区域中创建,str引用指向在堆内存位置中创建的对象。

如果你想要str引用String常量池中包含的点对象,则必须显式调用str.intern();

String str = "world";

它将检查字符串常量池是否已经包含字符串“hello”? 如果存在,则不会在String常量池中添加条目。如果不存在,它将在String常量池中添加一个条目。

在上述两种情况下,str引用指向常量池中存在的字符串“world”。

其他回答

当你使用一些东西,如new String(“Hello World”),SpotBugs代码分析工具,抱怨一个性能问题。

这个问题的描述显示了新字符串和常量字符串的区别

使用java.lang.String(String)构造函数会浪费内存,因为 这样构造的对象将在功能上难以区分 作为参数传递的字符串。只需使用参数String 直接。 错误类型和模式:Dm - DM_STRING_CTOR

抱歉回复晚了,但我急需回复。 首先,我们需要知道一些Java.lang.String类规则。

String Literals e.g.String str="java"; (we use only double Quotes) are different from String Object (we use new keyword) e.g. String str=new String("java"); String is Immutable Object i.e. If value changes a new Object is created and returned to you eg See replace() and replaceAll() functions and many more. This creates a problem of many String Object in Modification, So creators of Java came up an Idea was called StringPool. StringPool is stored in heap area where object reference data will be stored as we know String is Char[](before java 9 very Long to read) or byte[](after java 9 short to read). String literals are stored in StringPool and String Objects are stored in as usual heap Object Area. If there are many Object String Initialization JVM heap will be finished in String Operations only, Java Development team came up with intern() solution this moves/changes memory reference to StringPool. Program: Comparing String references to objects

另一个更好地理解java.lang.String的好链接

import java.util.*; 

class GFG { 
    public static void main(String[] args) 
    { 
      String siteName1 = "java.com";
        String siteName2 = "java.com";
        String siteName3 = new String("java.com");
        String siteName4 = new String("java.com").intern();
      
    System.out.println("siteName1:::"+Integer.toHexString(System.identityHashCode(siteName1)));
      System.out.println("siteName2:::"+Integer.toHexString(System.identityHashCode(siteName2)));
      System.out.println("siteName3 creation Of New Object Without Interned:::"+Integer.toHexString(System.identityHashCode(siteName3)));//must be Diffrent bcoz new Object In Heap Area
      System.out.println("siteName4 creation Of New Object With Interned:::"+Integer.toHexString(System.identityHashCode(siteName4)));//must be same MemoryAddress of siteName1,siteName2 and Interned, bcoz Objects Points to String pool Now
      
      System.out.println(siteName1 == siteName2); // true
      System.out.println(siteName1 == siteName3); // false this tells about lietral vs String Objects
      String siteName5 = siteName3.intern(); // Interning will not change Original Object but gives us a new Object
      
      System.out.println("siteName5 Interned from siteName3:::"+Integer.toHexString(System.identityHashCode(siteName5)));//must be same MemoryAddress of siteName1,siteName2 and Interned, bcoz Objects Points to String pool Now
      
      System.out.println(siteName1 == siteName3); // false this tells about Immutability
      System.out.println(siteName1 == siteName5); // true After Intering both are same
      System.out.println(siteName1 == siteName4); // true
      System.out.println(siteName5 == siteName4); // true
    } 
}

在字符串字面值池中创建任何字符串字面值,并且池不允许任何副本。因此,如果两个或多个字符串对象初始化为相同的字面值,那么所有对象将指向相同的字面值。

String obj1 = "abc";
String obj2 = "abc";

"obj1"和"obj2"将指向相同的字符串字面量,字符串字面量池将只有一个"abc"字面量。

当我们使用new关键字创建String类对象时,这样创建的字符串存储在堆内存中。任何作为参数传递给string类的构造函数的字符串字面值都存储在字符串池中。如果我们使用new操作符使用相同的值创建多个对象,每次都会在堆中创建一个新对象,因为应该避免使用这个new操作符。

String obj1 = new String("abc");
String obj2 = new String("abc");

"obj1"和"obj2"将指向堆中两个不同的对象,字符串字面量池将只有一个"abc"字面量。

关于字符串的行为还有一点值得注意,那就是任何对字符串进行的赋值或连接都会在内存中创建一个新对象。

String str1 = "abc";
String str2 = "abc" + "def";
str1 = "xyz";
str2 = str1 + "ghi";

在上面的例子中: 第1行:“abc”字面值存储在字符串池中。 第2行:"abcdef"字面值存储在字符串池中。 第3行:一个新的“xyz”字面值存储在字符串池中,“str1”开始指向这个字面值。 第4行:由于该值是通过附加到另一个变量而生成的,因此结果存储在堆内存中,被附加的字面量“ghi”将在字符串池中检查是否存在,并将被创建,因为在上述情况下它不存在。

尽管从程序员的角度来看,它们看起来是一样的,但它对性能有很大的影响。你几乎总是想用第一种形式。

新的字符串(“文本”); 显式地创建String对象的一个新的引用不同的实例;字符串s = "text";可以重用字符串常量池中的实例(如果有)。

你很少会想要使用新的String(anotherString)构造函数。来自API:

String(String original):初始化新创建的String对象,使其表示与参数相同的字符序列;换句话说,新创建的字符串是参数字符串的副本。除非需要original的显式副本,否则使用此构造函数是不必要的,因为字符串是不可变的。

相关问题

Java字符串:“字符串s =新字符串(“愚蠢的”);” 字符串是Java中的对象,所以为什么我们不使用' new '来创建它们呢?


什么是指涉区别

检查下面的代码片段:

    String s1 = "foobar";
    String s2 = "foobar";

    System.out.println(s1 == s2);      // true

    s2 = new String("foobar");
    System.out.println(s1 == s2);      // false
    System.out.println(s1.equals(s2)); // true

两个引用类型上的==是引用标识符比较。两个相等的对象不一定是==。在引用类型上使用==通常是错误的;大多数时候应该用等号代替。

尽管如此,如果出于某种原因需要创建两个equals而不是== string,则可以使用新的string (anotherString)构造函数。然而,需要再次说明的是,这是非常奇怪的,而且很少是故意的。

参考文献

JLS 15.21.3引用相等操作符==和!= 类对象-布尔对象(等于)

相关问题

Java字符串。等于和== 我如何比较字符串在Java?