Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.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 字符串与StringBuilder-对象数_Java_String_Stringbuilder - Fatal编程技术网

Java 字符串与StringBuilder-对象数

Java 字符串与StringBuilder-对象数,java,string,stringbuilder,Java,String,Stringbuilder,我遇到了两个代码片段,它们正在创建一个要进一步执行的查询: StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("SELECT * FROM EMPLOYEE "); stringBuilder.append("WHERE SALARY > ? "); stringBuilder.append("GROUP BY DEPT"); 及 根据我的分析,这两个片段都创建了4个对象。第一个代码段创建

我遇到了两个代码片段,它们正在创建一个要进一步执行的查询:

StringBuilder stringBuilder = new StringBuilder(); 
stringBuilder.append("SELECT * FROM EMPLOYEE "); 
stringBuilder.append("WHERE SALARY > ? "); 
stringBuilder.append("GROUP BY DEPT");

根据我的分析,这两个片段都创建了4个对象。第一个代码段创建一个StringBuilder对象和3个string对象,而第二个代码段创建4个string对象。我的分析正确吗


代码段1如何比代码段2更有效?

您的第一个分析是正确的,但第二个代码段只创建了一个字符串对象。因为,它是字符串和文本的编译时串联。

不完全是

第一个版本在每次执行时创建1个
StringBuilder
和3个
String
常量(在每次JVM启动时创建/一次)。每次执行时,当您通过
stringBuilder.toString()
使用该值时,它将创建另一个
String
对象

第二个创建1
String
常量(每个JVM启动创建/一次),因为整个连接的值在编译时是已知的。它实际上等同于:

String string = "SELECT * FROM EMPLOYEE WHERE SALARY > ? GROUP BY DEPT";

字符串是不可变的,因此每次执行串联(.operator)操作时,您都在内存中创建一个新的字符串对象。使用StringBuilder,您将文本添加到同一对象中,因此不需要创建新的文本。

示例将创建4个对象

而第二个示例将只创建一个字符串对象。即使您已经连接了3个
字符串
文本,模型Java编译器也足够智能,可以检测到您已经连接了静态
字符串
文本,因此将把所有字符串
附加到一个字符串中,并创建一个
字符串
对象

所以,

String string = "SELECT * FROM EMPLOYEE " +
"WHERE SALARY > ? " +
"GROUP BY DEPT";

String string = "SELECT * FROM EMPLOYEE WHERE SALARY > ? GROUP BY DEPT";

第一个代码段创建一个对象。它在编译时进行连接

连接可变字符串时,StringBuilder具有更好的性能。例如,以您的示例:

StringBuilder stringBuilder = new StringBuilder(); 
stringBuilder.append("SELECT * FROM EMPLOYEE "); 
if(salary > 0) {
    stringBuilder.append("WHERE SALARY > ? "); 
}
if(group == true) {
    stringBuilder.append("GROUP BY DEPT");
}

String string = "SELECT * FROM EMPLOYEE ";
if(salary > 0) {
    string = string + "WHERE SALARY > ? ";
}
if(group == true) {
    string = = string + "GROUP BY DEPT";
}

很明显,连接可以在编译时完成。然而,编译器有义务这么做吗?如今,当人们谈论没有安卓标签的“java”时,可以安全地假设它是热点编译器,然后是的,它会发生。如果您构建自己的编译器,您就没有义务进行编译时连接,因为它在功能上仍然正确。@NPE根据我的说法,编译器没有义务这样做。谢谢您的输入。@DarshanMehta,欢迎您!还有。伙计。。。
StringBuilder stringBuilder = new StringBuilder(); 
stringBuilder.append("SELECT * FROM EMPLOYEE "); 
if(salary > 0) {
    stringBuilder.append("WHERE SALARY > ? "); 
}
if(group == true) {
    stringBuilder.append("GROUP BY DEPT");
}

String string = "SELECT * FROM EMPLOYEE ";
if(salary > 0) {
    string = string + "WHERE SALARY > ? ";
}
if(group == true) {
    string = = string + "GROUP BY DEPT";
}