关于java:创建了多少个对象,包括String对象

How many objects are created including String objects

本问题已经有最佳答案,请猛点这里访问。

有人能告诉我创建了多少个对象吗?S3是否引用了字符串池中的相同hello?有多少个字符串对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
 *
 */

 package agnitio;

/**
 * @author admin
 *
 */

public class TestString {

/**
 * @param args
 */

public static void main(String[] args) {
    // TODO Auto-generated method stub
    String s1="hello";
    String s2="hello";
    String s3 = new String("hello");
    System.out.println(s1==s2); // true
    System.out.println(s1==s3); // false
    System.out.println(s2==s3); // false

}

}


只创建两个对象。第一个对象:

1
String s1="hello";

执行以下操作时,不会在内存中创建任何对象:

1
String s2="hello";

这是因为JVM字符串类是基于flyweight模式的,所以如果内存中已经存在一个字符串,就像您的例子"hello"一样,那么创建一个新的引用将不会创建一个新的对象。s1和s2都将指向相同的内存位置。

第二个对象是在执行以下操作时创建的:

1
String s3 = new String("hello");

因为new操作符总是创建一个新对象。

==比较两个引用是否指向相同的内存位置。while equals比较字符串的内容。我说过,正如我所提到的,s1和s2都指向相同的内存位置,因此,==和等于都将返回true进行比较。但是s3是一个不同的对象,因此将s1和s2与==操作进行比较将返回false。但是如果你把s1、s2和s3做比较,你会得到正确的结果。


不,想象一下StringPool工具没有使字符串不可变,这根本不可能,因为在字符串池中,一个字符串对象/文字(例如"hello")被许多引用变量引用,因此如果其中任何一个更改了值,其他的都会自动受到影响,例如

1
2
String A ="hello"
String B ="hello"

现在字符串b称为"hello".toUpperCase(),它将同一对象更改为"test",因此a也将是"test",这是不可取的。

编辑编辑

如果我们谈论的是有多少个字符串对象:

1
2
String s ="hello";    // one string object in the string pool"hello"
String s2 ="hello";   // two object variables (s, s2)

在这个简单的例子中,"abc"将进入池中,s和s2将引用它。

1
String s3 = new String("hello"); // creates two objects, and one reference variable.

在这种情况下,因为我们使用了new关键字,Java将创建一个新的字符串对象在正常(非池)内存中,S将引用它。此外,"你好"也将放置在池中(如果不存在)。


.equals()方法根据该字符串中的值(存在的内容)匹配两个字符串,==检查两个对象是否指向同一引用。

检查下面的链接,你会得到你的答案,

difference between == and equals method


使用String.ContentEquals:

1
"stringA".contentEquals("StringB");

字符串是对象,无论何时创建"新字符串",它实际上都会创建一个指向内存中某个位置的"新字符串(值)",例如,"float"是一个基元/值,而float是一个指向内存中某个位置的指针的对象。使用"=="时,只需检查指针是否相同。"string.contentEquals"检查两个对象的内容是否相同。