如何在Java 9中实现String连接? [英] How is String concatenation implemented in Java 9?
问题描述
如 JEP 280 所述:
更改由
javac
生成的静态String
-concatenation字节码序列以使用invokedynamic
调用JDK库函数。这将允许将来优化String
连接,而无需进一步更改javac
所包含的字节码。
Change the static
String
-concatenation bytecode sequence generated byjavac
to useinvokedynamic
calls to JDK library functions. This will enable future optimizations ofString
concatenation without requiring further changes to the bytecode emmited byjavac
.
这里我想了解 invokedynamic
调用的用法以及字节码串联与 invokedynamic
?
Here I want to understand what the use of invokedynamic
calls is and how bytecode concatenation is different from invokedynamic
?
推荐答案
旧方式输出一堆 StringBuilder
- 面向操作。考虑这个程序:
The "old" way output a bunch of StringBuilder
-oriented operations. Consider this program:
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
查看字节码,我们看到如下内容:
If we compile that with JDK 8 or earlier and then use javap -c Example
to see the bytecode, we see something like this:
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
并使用附加
。这是着名的低效率,因为 StringBuilder
中内置缓冲区的默认容量只有16个字符,编译器无法使用知道提前分配更多,所以最终不得不重新分配。它也是一堆方法调用。 (请注意,JVM可以有时检测并重写这些调用模式,以提高它们的效率。)
As you can see, it creates a StringBuilder
and uses append
. This is famous fairly inefficient as the default capacity of the built-in buffer in StringBuilder
is only 16 chars, and there's no way for the compiler to know to allocate more in advance, so it ends up having to reallocate. It's also a bunch of method calls. (Note that the JVM can sometimes detect and rewrite these patterns of calls to make them more efficient, though.)
让我们来看看Java是什么9生成:
Let's look at what Java 9 generates:
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
}
哦,我的但是更短。 :-)它从 makeConcatWithConstants /invoke/StringConcatFactory.html\"rel =noreferrer> StringConcatFactory
,在其Javadoc中说明这一点:
Oh my but that's shorter. :-) It makes a single call to makeConcatWithConstants
from StringConcatFactory
, which says this in its Javadoc:
有助于创建字符串连接方法的方法,可用于有效地连接已知类型的已知类型的参数,可能在类型调整和参数的部分评估之后。这些方法通常用作
invokedynamic
调用站点的引导方法,以支持Java编程的字符串连接功能语言。
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 9中实现String连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!