Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中的对象生命周期和内存管理?_Java_String_Object_Heap Memory - Fatal编程技术网

java中的对象生命周期和内存管理?

java中的对象生命周期和内存管理?,java,string,object,heap-memory,Java,String,Object,Heap Memory,对于程序中的以下语句,将在堆内存和字符串常量池中创建多少个对象 我需要清晰的对象创建。我读过的许多资料都没有详细说明。当物体被摧毁时,我感到困惑 String a="MAM"+"BCD"+"EFG"+"GFE"; 将创建多少个对象 我正在寻找关于对象、方法和类的生命周期的好资料,以及JVM在动态更改和修改它们时如何处理它们。只创建一个对象 string s1 = "java"; string s2 = "ja" + "va"; s.o.p(s1==s2); 这句话是真的 String s1=

对于程序中的以下语句,将在堆内存和字符串常量池中创建多少个对象

我需要清晰的对象创建。我读过的许多资料都没有详细说明。当物体被摧毁时,我感到困惑

String a="MAM"+"BCD"+"EFG"+"GFE";
将创建多少个对象


我正在寻找关于对象、方法和类的生命周期的好资料,以及JVM在动态更改和修改它们时如何处理它们。

只创建一个对象

string s1 = "java";
string s2 = "ja" + "va";
s.o.p(s1==s2);
这句话是真的

String s1="java";
string s2 = "ja";
String s3 = s2 +"va";
s.o.p(s1==s3);
这种说法是错误的

所以最小的一个表观值应该是永久的,然后“+”操作符生成新的字符串对象(在非常量池中使用new())。
所以,你问的问题没有一个也是永久的。这意味着它只创建一个对象。

仅创建一个对象并将其放置在常量池中,除非该对象已经存在,在这种情况下,将使用现有对象。编译器将字符串常量连接在一起,如JLS 3.10.5和15.28中所述

长字符串文字总是可以分解为较短的片段,并使用字符串连接运算符作为表达式(可能是括号)写入+

“MAM”+“BCD”+“EFG”+“GFE”
是一个编译时常量表达式,它编译成
“MAMBCDEFGGFE”
字符串文字。当加载包含上述代码的类时,JVM将从此文本创建
String
的实例,并将此
String
放入字符串池。因此
String a=“MAM”+“BCD”+“EFG”+“GFE”不创建任何对象,请参见JLS
15.18.1。字符串连接运算符+

字符串对象是新创建的(§12.5),除非表达式是编译时常量表达式(§15.28)


它只是将池中
String
对象的引用分配给本地var
a

只创建一个对象,因为
String a
将编译成
“MAMBCDEFGGFE”

在您的示例中说明单个堆对象的答案是正确的。但是,请考虑这个代码:

public class Tester
{
   public String a="MAM";
   public String b ="BCD";
   public String c = "EFG";
   public String d ="GFE";

   public Tester()
   {
      String abcd = a + b + c + d;
   }
}
在本例中,创建了7个字符串。a、 b、c和d并没有被编译成一个常数——它们是成员。然后为每个
+
运算符创建一个字符串-从语义上讲,
+
是一个串联,但从逻辑上讲,它在内存中创建一个新字符串。前2个运算符字符串立即被丢弃,现在可以进行垃圾回收,但内存仍然会发生翻腾

从技术上讲,在第八个物体中。Tester的实例


编辑:这在评论中被证明是无稽之谈

大多数答案似乎集中于a)完整表达式是一个编译时常数,b)行本身不构造新对象,而只是对一个对象的引用

然而,到目前为止还没有人提到,
String
本身包含对内部
char[]
(也在常量池中)的引用

摘要:常量池中有两个对象(
String
char[]
)。该线既不会创建也不会破坏任何对象

关于:

当物体被摧毁时,我感到困惑

String a="MAM"+"BCD"+"EFG"+"GFE";

没有对象被销毁,因为常量池中的内容只有在类本身被卸载时才会被销毁。最多您可以说,引用
a
最终将超出范围。

应该有人在其上运行
javah
。我敢打赌它只会显示一个常量。对我来说只有一个,但讨论中的许多朋友让我困惑,javac编译器有一个优化:不是每个
+
都会生成一个新字符串。在读取时,创建一个内部
StringBuilder
a
b
c
c
,然后创建一个
字符串。这种优化已经存在十多年了。所以计算是5 <代码>字符串< /代码>和5相关联的<代码> char [] /代码>,1 <代码> StringBuilder < /代码>加上至少一个关联的<代码> char []/Cord>——最终更多地是由于动态调整大小。U表示它将首先附加A+B,然后将+B看作一个字符串并附加到C??我不明白你的意思