当前位置: 首页 > 面试题库 >

当Java编译器在一行中看到许多String串联时会发生什么?

单喜
2023-03-14
问题内容

假设我有一个Java表达式,例如:

String s = "abc" + methodReturningAString() + "ghi" + 
                anotherMethodReturningAString() + "omn" + "blablabla";

Java的默认JDK编译器的行为是什么?它只是进行了五个串联,还是完成了一个聪明的性能技巧?


问题答案:

它产生的等价于:

String s = new StringBuilder("abc")
           .append(methodReturningAString())
           .append("ghi")
           .append(anotherMethodReturningAString())
           .append("omn")
           .append("blablabla")
           .toString();

预先连接静态字符串(即 "omn" + "blablabla")足够聪明 。如果需要,可以调用StringBuilder“性能技巧”。对于性能而言,绝对比执行五个串联导致四个不必要的临时字符串更好。另外,使用StringBuilder可以提高Java
5的性能。在此之前,使用StringBuffer。

编辑
:如注释中所指出的,仅当静态字符串位于串联的开头时才进行预串联。否则将破坏操作顺序(尽管在这种情况下,我认为Sun可以证明其合理性)。因此,鉴于此:

String s = "abc" + "def" + foo() + "uvw" + "xyz";

它将像这样编译:

String s = new StringBuilder("abcdef")
           .append(foo())
           .append("uvw")
           .append("xyz")
           .toString();


 类似资料:
  • 这三个方法包含相同的参数,所以不应该重载。它们都有执行不同功能的代码。这怎么可能?java如何知道调用哪个方法?在命令行中通过java jar命令执行此代码时,我没有得到任何错误。

  • 发生在运行时,因为编译器不能在决定执行哪个函数,但为什么编译器不能在编译时决定呢? 产出: 狗在吃...

  • 我在yarn cluster上运行的spark应用程序崩溃了,我正在试图确定根本原因。在我使用从yarn获得的日志中,我看到在块获取期间有一大堆连接被拒绝,还有一个内存不足错误。很难说出根本原因是什么。我的问题是当容器因为OutOfMemory异常而被杀死时会发生什么。因此,在容器日志中,我看到这是如何在容器上启动执行器的 我还看到许多。在应用程序崩溃之前,似乎有多个这样的问题。spark重试一个

  • 我是Java新手,来自C语言背景,我试图理解接口和实现接口的抽象类的概念。当抽象类实现接口时,会发生什么?这是否像继承一样工作,即所有接口方法都属于abtract类,即使它们没有在其中实现?还是只有实现的方法属于抽象类?那么,除了一个用于实现接口,另一个用于继承之外,实现和扩展之间有什么区别吗?

  • 如果在java中执行关闭挂钩期间引发了未捕获的异常,jvm是否会立即退出,而不运行其余已注册的关闭挂钩(如果有)?从javadocs: 未捕获的异常通过调用线程ThreadGroup对象的uncaughtException方法在关闭钩子中处理,就像在任何其他线程中一样。此方法的默认实现将异常的堆栈跟踪打印到System.err并终止线程;它不会导致虚拟机退出或停止。 似乎其他关机挂钩应该运行...

  • 问题内容: 几天后,我匆忙将一个URL错误地粘贴到了Java程序中,我试图运行该特定程序,并且出于好奇,它成功运行了,没有任何警告,没有错误,也没有异常。类似的代码如下所示。我编译并成功运行。 在main()方法的第二行,它应该发出一些编译时错误,但它可以很好地工作并在控制台上显示相应的消息。为什么? 问题答案: 标记被解释为标签。而随后启动一个新的行注释。因此,发布的代码仍然是有效的Java(如