gpt4 book ai didi

java - Java 9 中的字符串连接是如何实现的?

转载 作者:行者123 更新时间:2023-12-05 07:08:09 24 4
gpt4 key购买 nike

写在JEP 280: Indify String Concatenation :

Change the static String-concatenation bytecode sequence generated by javac to use invokedynamic calls to JDK library functions. This will enable future optimizations of String concatenation without requiring further changes to the bytecode emmited by javac.

这里我想了解一下invokedynamic调用的用途是什么,字节码拼接和invokedynamic有什么不同?

最佳答案

“旧”方式输出一堆面向 StringBuilder 的操作。考虑这个程序:

public class Example {
public static void main(String[] args)
{
String result = args[0] + "-" + args[1] + "-" + args[2];
System.out.println(result);
}
}

如果我们使用 JDK 8 或更早版本编译它,然后使用 javap -c Example 查看字节码,我们会看到如下内容:

public class Example {  public Example();    Code:       0: aload_0       1: invokespecial #1                  // Method java/lang/Object."<init>":()V       4: return  public static void main(java.lang.String[]);    Code:       0: new           #2                  // class java/lang/StringBuilder       3: dup       4: invokespecial #3                  // Method java/lang/StringBuilder."<init>":()V       7: aload_0       8: iconst_0       9: aaload      10: invokevirtual #4                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;      13: ldc           #5                  // String -      15: invokevirtual #4                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;      18: aload_0      19: iconst_1      20: aaload      21: invokevirtual #4                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;      24: ldc           #5                  // String -      26: invokevirtual #4                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;      29: aload_0      30: iconst_2      31: aaload      32: invokevirtual #4                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;      35: invokevirtual #6                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;      38: astore_1      39: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;      42: aload_1      43: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V      46: return}

如您所见,它创建了一个 StringBuilder 并使用了 append。这是众所周知的相当低效的做法,因为 StringBuilder 中内置缓冲区的默认容量仅为 16 个字符,编译器 无法提前知道分配更多字符,所以它最终不得不重新分配。它也是一堆方法调用。 (不过请注意,JVM 有时 可以检测并重写这些调用模式以提高它们的效率。)

让我们看看 Java 9 生成了什么:

public class Example {  public Example();    Code:       0: aload_0       1: invokespecial #1                  // Method java/lang/Object."<init>":()V       4: return  public static void main(java.lang.String[]);    Code:       0: aload_0       1: iconst_0       2: aaload       3: aload_0       4: iconst_1       5: aaload       6: aload_0       7: iconst_2       8: aaload       9: invokedynamic #2,  0              // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;      14: astore_1      15: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;      18: aload_1      19: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V      22: return}

哦,天哪,但那更短了。 :-) 它从 StringConcatFactory 调用 makeConcatWithConstants ,在它的 Javadoc 中这样说:

Methods to facilitate the creation of String concatenation methods, that can be used to efficiently concatenate a known number of arguments of known types, possibly after type adaptation and partial evaluation of arguments. These methods are typically used as bootstrap methods for invokedynamic call sites, to support the string concatenation feature of the Java Programming Language.

关于java - Java 9 中的字符串连接是如何实现的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61918877/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com